diff --git a/communication/src/main/java/datadog/communication/ddagent/DDAgentFeaturesDiscovery.java b/communication/src/main/java/datadog/communication/ddagent/DDAgentFeaturesDiscovery.java index f9cc3eda3e0..8fdee5d5daa 100644 --- a/communication/src/main/java/datadog/communication/ddagent/DDAgentFeaturesDiscovery.java +++ b/communication/src/main/java/datadog/communication/ddagent/DDAgentFeaturesDiscovery.java @@ -97,16 +97,198 @@ private static class State { String telemetryProxyEndpoint; Set peerTags = emptySet(); long lastTimeDiscovered; + + public String getTraceEndpoint() { + return traceEndpoint; + } + + public String getMetricsEndpoint() { + return metricsEndpoint; + } + + public String getDataStreamsEndpoint() { + return dataStreamsEndpoint; + } + + public boolean isSupportsLongRunning() { + return supportsLongRunning; + } + + public boolean isSupportsDropping() { + return supportsDropping; + } + + public String getState() { + return state; + } + + public String getConfigEndpoint() { + return configEndpoint; + } + + public String getDebuggerLogEndpoint() { + return debuggerLogEndpoint; + } + + public String getDebuggerSnapshotEndpoint() { + return debuggerSnapshotEndpoint; + } + + public String getDebuggerDiagnosticsEndpoint() { + return debuggerDiagnosticsEndpoint; + } + + public String getEvpProxyEndpoint() { + return evpProxyEndpoint; + } + + public String getVersion() { + return version; + } + + public String getTelemetryProxyEndpoint() { + return telemetryProxyEndpoint; + } + + public Set getPeerTags() { + return peerTags; + } + + public long getLastTimeDiscovered() { + return lastTimeDiscovered; + } + + void allowIO() {} + } + + private class UndiscoveredState extends State { + private boolean ioAllowed; + + public UndiscoveredState(boolean ioAllowed) { + this.ioAllowed = ioAllowed; + } + + @Override + void allowIO() { + this.ioAllowed = true; + } + + private void doDiscovery() { + if (ioAllowed) { + DDAgentFeaturesDiscovery.this.discoverIfOutdated(); + } + } + + @Override + public String getTraceEndpoint() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getTraceEndpoint(); + } + + @Override + public String getMetricsEndpoint() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getMetricsEndpoint(); + } + + @Override + public String getDataStreamsEndpoint() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getDataStreamsEndpoint(); + } + + @Override + public boolean isSupportsLongRunning() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.isSupportsLongRunning(); + } + + @Override + public boolean isSupportsDropping() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.isSupportsDropping(); + } + + @Override + public String getState() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getState(); + } + + @Override + public String getConfigEndpoint() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getConfigEndpoint(); + } + + @Override + public String getDebuggerLogEndpoint() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getDebuggerLogEndpoint(); + } + + @Override + public String getDebuggerSnapshotEndpoint() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getDebuggerSnapshotEndpoint(); + } + + @Override + public String getDebuggerDiagnosticsEndpoint() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getDebuggerDiagnosticsEndpoint(); + } + + @Override + public String getEvpProxyEndpoint() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getEvpProxyEndpoint(); + } + + @Override + public String getVersion() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getVersion(); + } + + @Override + public String getTelemetryProxyEndpoint() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getTelemetryProxyEndpoint(); + } + + @Override + public Set getPeerTags() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getPeerTags(); + } + + @Override + public long getLastTimeDiscovered() { + doDiscovery(); + return DDAgentFeaturesDiscovery.this.discoveryState.getLastTimeDiscovered(); + } } private volatile State discoveryState; - public DDAgentFeaturesDiscovery( + // kept for testing + protected DDAgentFeaturesDiscovery( OkHttpClient client, Monitoring monitoring, HttpUrl agentUrl, boolean enableV05Traces, boolean metricsEnabled) { + this(client, monitoring, agentUrl, enableV05Traces, metricsEnabled, true); + } + + public DDAgentFeaturesDiscovery( + OkHttpClient client, + Monitoring monitoring, + HttpUrl agentUrl, + boolean enableV05Traces, + boolean metricsEnabled, + boolean ioAllowed) { this.client = client; this.agentBaseUrl = agentUrl; this.metricsEnabled = metricsEnabled; @@ -115,7 +297,7 @@ public DDAgentFeaturesDiscovery( ? new String[] {V5_ENDPOINT, V4_ENDPOINT, V3_ENDPOINT} : new String[] {V4_ENDPOINT, V3_ENDPOINT}; this.discoveryTimer = monitoring.newTimer("trace.agent.discovery.time"); - this.discoveryState = new State(); + this.discoveryState = new UndiscoveredState(ioAllowed); } /** Run feature discovery, unconditionally. */ @@ -145,6 +327,7 @@ private synchronized void discoverIfOutdated(final long maxElapsedMs) { } private void doDiscovery(State newState) { + discoveryState.allowIO(); // 1. try to fetch info about the agent, if the endpoint is there // 2. try to parse the response, if it can be parsed, finish // 3. fallback if the endpoint couldn't be found or the response couldn't be parsed @@ -356,51 +539,51 @@ private static void discoverStatsDPort(final Map info) { } public boolean supportsMetrics() { - return metricsEnabled && null != discoveryState.metricsEndpoint; + return metricsEnabled && null != discoveryState.getMetricsEndpoint(); } public boolean supportsDebugger() { - return discoveryState.debuggerLogEndpoint != null; + return discoveryState.getDebuggerLogEndpoint() != null; } public String getDebuggerSnapshotEndpoint() { - return discoveryState.debuggerSnapshotEndpoint; + return discoveryState.getDebuggerSnapshotEndpoint(); } public String getDebuggerLogEndpoint() { - return discoveryState.debuggerLogEndpoint; + return discoveryState.getDebuggerLogEndpoint(); } public boolean supportsDebuggerDiagnostics() { - return discoveryState.debuggerDiagnosticsEndpoint != null; + return discoveryState.getDebuggerDiagnosticsEndpoint() != null; } public boolean supportsDropping() { - return discoveryState.supportsDropping; + return discoveryState.isSupportsDropping(); } public boolean supportsLongRunning() { - return discoveryState.supportsLongRunning; + return discoveryState.isSupportsLongRunning(); } public Set peerTags() { - return discoveryState.peerTags; + return discoveryState.getPeerTags(); } public String getMetricsEndpoint() { - return discoveryState.metricsEndpoint; + return discoveryState.getMetricsEndpoint(); } public String getTraceEndpoint() { - return discoveryState.traceEndpoint; + return discoveryState.getTraceEndpoint(); } public String getDataStreamsEndpoint() { - return discoveryState.dataStreamsEndpoint; + return discoveryState.getDataStreamsEndpoint(); } public String getEvpProxyEndpoint() { - return discoveryState.evpProxyEndpoint; + return discoveryState.getEvpProxyEndpoint(); } public HttpUrl buildUrl(String endpoint) { @@ -408,25 +591,25 @@ public HttpUrl buildUrl(String endpoint) { } public boolean supportsDataStreams() { - return discoveryState.dataStreamsEndpoint != null; + return discoveryState.getDataStreamsEndpoint() != null; } public boolean supportsEvpProxy() { - return discoveryState.evpProxyEndpoint != null; + return discoveryState.getEvpProxyEndpoint() != null; } public boolean supportsContentEncodingHeadersWithEvpProxy() { // content encoding headers are supported in /v4 and above - final String evpProxyEndpoint = discoveryState.evpProxyEndpoint; + final String evpProxyEndpoint = discoveryState.getEvpProxyEndpoint(); return evpProxyEndpoint != null && V4_EVP_PROXY_ENDPOINT.compareTo(evpProxyEndpoint) <= 0; } public String getConfigEndpoint() { - return discoveryState.configEndpoint; + return discoveryState.getConfigEndpoint(); } public String getVersion() { - return discoveryState.version; + return discoveryState.getVersion(); } private void errorQueryingEndpoint(String endpoint, Throwable t) { @@ -434,15 +617,15 @@ private void errorQueryingEndpoint(String endpoint, Throwable t) { } public String state() { - return discoveryState.state; + return discoveryState.getState(); } @Override public boolean active() { - return supportsMetrics() && discoveryState.supportsDropping; + return supportsMetrics() && discoveryState.isSupportsLongRunning(); } public boolean supportsTelemetryProxy() { - return discoveryState.telemetryProxyEndpoint != null; + return discoveryState.getTelemetryProxyEndpoint() != null; } } diff --git a/communication/src/main/java/datadog/communication/ddagent/SharedCommunicationObjects.java b/communication/src/main/java/datadog/communication/ddagent/SharedCommunicationObjects.java index 9cea9990cbf..67b78dcfdd4 100644 --- a/communication/src/main/java/datadog/communication/ddagent/SharedCommunicationObjects.java +++ b/communication/src/main/java/datadog/communication/ddagent/SharedCommunicationObjects.java @@ -1,7 +1,6 @@ package datadog.communication.ddagent; import static datadog.communication.ddagent.TracerVersion.TRACER_VERSION; -import static datadog.trace.util.AgentThreadFactory.AGENT_THREAD_GROUP; import datadog.common.container.ContainerInfo; import datadog.common.socket.SocketUtils; @@ -10,7 +9,6 @@ import datadog.remoteconfig.ConfigurationPoller; import datadog.remoteconfig.DefaultConfigurationPoller; import datadog.trace.api.Config; -import datadog.trace.util.AgentTaskScheduler; import java.security.Security; import java.util.ArrayList; import java.util.List; @@ -78,7 +76,7 @@ public void resume() { paused = false; // attempt discovery first to avoid potential race condition on IBM Java8 if (null != featuresDiscovery) { - featuresDiscovery.discoverIfOutdated(); + // featuresDiscovery.discoverIfOutdated(); } else { Security.getProviders(); // fallback to preloading provider extensions } @@ -150,18 +148,8 @@ public DDAgentFeaturesDiscovery featuresDiscovery(Config config) { monitoring, agentUrl, config.isTraceAgentV05Enabled(), - config.isTracerMetricsEnabled()); - - if (paused) { - // defer remote discovery until remote I/O is allowed - } else { - if (AGENT_THREAD_GROUP.equals(Thread.currentThread().getThreadGroup())) { - ret.discover(); // safe to run on same thread - } else { - // avoid performing blocking I/O operation on application thread - AgentTaskScheduler.get().execute(ret::discoverIfOutdated); - } - } + config.isTracerMetricsEnabled(), + !paused); featuresDiscovery = ret; } } diff --git a/dd-trace-core/src/main/java/datadog/trace/common/writer/DDAgentWriter.java b/dd-trace-core/src/main/java/datadog/trace/common/writer/DDAgentWriter.java index 50b9aba2cdb..dd377c3bc60 100644 --- a/dd-trace-core/src/main/java/datadog/trace/common/writer/DDAgentWriter.java +++ b/dd-trace-core/src/main/java/datadog/trace/common/writer/DDAgentWriter.java @@ -143,7 +143,7 @@ public DDAgentWriter build() { if (null == featureDiscovery) { featureDiscovery = new DDAgentFeaturesDiscovery( - client, monitoring, agentUrl, traceAgentV05Enabled, metricsReportingEnabled); + client, monitoring, agentUrl, traceAgentV05Enabled, metricsReportingEnabled, true); } if (null == agentApi) { agentApi = diff --git a/utils/config-utils/build.gradle.kts b/utils/config-utils/build.gradle.kts index ccf2e03f6fb..6eb83667c3e 100644 --- a/utils/config-utils/build.gradle.kts +++ b/utils/config-utils/build.gradle.kts @@ -1,6 +1,6 @@ plugins { `java-library` - id("supported-config-generator") + // id("supported-config-generator") } apply(from = "$rootDir/gradle/java.gradle")