From 0e85a14175626341bf2f41b8978033c91e43e079 Mon Sep 17 00:00:00 2001 From: Stuart McCulloch Date: Mon, 20 Jul 2026 11:37:11 +0100 Subject: [PATCH] Remove AgentTracer.noopContinuation() sentinel Call sites now check continuation.context() == Context.root() instead of comparing against a shared singleton, mirroring ThreadLocalContextManager. Co-Authored-By: Claude Sonnet 5 --- .../instrumentation/java/concurrent/Wrapper.java | 4 ++-- .../TraceContinuedFutureCallback.java | 8 ++++---- .../TraceContinuedFutureCallback.java | 8 ++++---- .../jetty12/JettyRunnableWrapper.java | 4 ++-- .../instrumentation/mongo/CallbackWrapper.java | 4 ++-- .../netty38/NettyChannelInstrumentation.java | 4 ++-- .../NettyChannelPipelineInstrumentation.java | 4 ++-- .../NettyChannelPipelineInstrumentation.java | 4 ++-- .../netty4/promise/ListenerWrapper.java | 4 ++-- .../src/test/groovy/OpenTracing31Test.groovy | 4 ++-- .../src/test/groovy/OpenTracing32Test.groovy | 4 ++-- .../SpannedMethodInvocation.java | 4 ++-- .../SynapseClientWorkerInstrumentation.java | 4 ++-- .../SynapseServerWorkerInstrumentation.java | 4 ++-- .../undertow/UndertowRunnableWrapper.java | 4 ++-- .../scopemanager/ContinuableScopeManager.java | 16 ++++++++++++---- .../scopemanager/ScopeManagerForkedTest.java | 5 ++--- .../instrumentation/api/AgentTracer.java | 15 +-------------- .../instrumentation/api/NoopContinuation.java | 6 +++--- .../lang/ProcessImplInstrumentationHelpers.java | 4 ++-- 20 files changed, 54 insertions(+), 60 deletions(-) diff --git a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/java/concurrent/Wrapper.java b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/java/concurrent/Wrapper.java index c870647534e..a26cc0c4535 100644 --- a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/java/concurrent/Wrapper.java +++ b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/java/concurrent/Wrapper.java @@ -1,10 +1,10 @@ package datadog.trace.bootstrap.instrumentation.java.concurrent; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; import static datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter.ExcludeType.RUNNABLE; import static datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter.exclude; +import datadog.context.Context; import datadog.context.ContextContinuation; import datadog.context.ContextScope; import java.util.concurrent.RunnableFuture; @@ -20,7 +20,7 @@ public static Runnable wrap(T task) { return task; } ContextContinuation continuation = captureActiveSpan(); - if (continuation != noopContinuation()) { + if (continuation.context() != Context.root()) { if (task instanceof Comparable) { return new ComparableRunnable(task, continuation); } diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/TraceContinuedFutureCallback.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/TraceContinuedFutureCallback.java index 52a9a5d8ee6..cebba8c14b9 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/TraceContinuedFutureCallback.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpasyncclient-4.0/src/main/java/datadog/trace/instrumentation/apachehttpasyncclient/TraceContinuedFutureCallback.java @@ -1,8 +1,8 @@ package datadog.trace.instrumentation.apachehttpasyncclient; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; import static datadog.trace.instrumentation.apachehttpasyncclient.ApacheHttpAsyncClientDecorator.DECORATE; +import datadog.context.Context; import datadog.context.ContextContinuation; import datadog.context.ContextScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -33,7 +33,7 @@ public void completed(final T result) { DECORATE.beforeFinish(clientSpan); clientSpan.finish(); // Finish span before calling delegate - if (parentContinuation == noopContinuation()) { + if (parentContinuation.context() == Context.root()) { completeDelegate(result); } else { try (final ContextScope scope = parentContinuation.resume()) { @@ -49,7 +49,7 @@ public void failed(final Exception ex) { DECORATE.beforeFinish(clientSpan); clientSpan.finish(); // Finish span before calling delegate - if (parentContinuation == noopContinuation()) { + if (parentContinuation.context() == Context.root()) { failDelegate(ex); } else { try (final ContextScope scope = parentContinuation.resume()) { @@ -64,7 +64,7 @@ public void cancelled() { DECORATE.beforeFinish(clientSpan); clientSpan.finish(); // Finish span before calling delegate - if (parentContinuation == noopContinuation()) { + if (parentContinuation.context() == Context.root()) { cancelDelegate(); } else { try (final ContextScope scope = parentContinuation.resume()) { diff --git a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/TraceContinuedFutureCallback.java b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/TraceContinuedFutureCallback.java index 67a1b940be8..771ee21a4a1 100644 --- a/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/TraceContinuedFutureCallback.java +++ b/dd-java-agent/instrumentation/apache-httpclient/apache-httpclient-5.0/src/main/java/datadog/trace/instrumentation/apachehttpclient5/TraceContinuedFutureCallback.java @@ -1,8 +1,8 @@ package datadog.trace.instrumentation.apachehttpclient5; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; import static datadog.trace.instrumentation.apachehttpclient5.ApacheHttpClientDecorator.DECORATE; +import datadog.context.Context; import datadog.context.ContextContinuation; import datadog.context.ContextScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -36,7 +36,7 @@ public void completed(final T result) { DECORATE.beforeFinish(clientSpan); clientSpan.finish(); // Finish span before calling delegate - if (parentContinuation == noopContinuation()) { + if (parentContinuation.context() == Context.root()) { completeDelegate(result); } else { try (final ContextScope scope = parentContinuation.resume()) { @@ -52,7 +52,7 @@ public void failed(final Exception ex) { DECORATE.beforeFinish(clientSpan); clientSpan.finish(); // Finish span before calling delegate - if (parentContinuation == noopContinuation()) { + if (parentContinuation.context() == Context.root()) { failDelegate(ex); } else { try (final ContextScope scope = parentContinuation.resume()) { @@ -67,7 +67,7 @@ public void cancelled() { DECORATE.beforeFinish(clientSpan); clientSpan.finish(); // Finish span before calling delegate - if (parentContinuation == noopContinuation()) { + if (parentContinuation.context() == Context.root()) { cancelDelegate(); } else { try (final ContextScope scope = parentContinuation.resume()) { diff --git a/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-12.0/src/main/java17/datadog/trace/instrumentation/jetty12/JettyRunnableWrapper.java b/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-12.0/src/main/java17/datadog/trace/instrumentation/jetty12/JettyRunnableWrapper.java index 7f74a35b959..62df546a1a0 100644 --- a/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-12.0/src/main/java17/datadog/trace/instrumentation/jetty12/JettyRunnableWrapper.java +++ b/dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-12.0/src/main/java17/datadog/trace/instrumentation/jetty12/JettyRunnableWrapper.java @@ -1,10 +1,10 @@ package datadog.trace.instrumentation.jetty12; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; import static datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter.ExcludeType.RUNNABLE; import static datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter.exclude; +import datadog.context.Context; import datadog.context.ContextContinuation; import datadog.context.ContextScope; @@ -30,7 +30,7 @@ public static Runnable wrapIfNeeded(final Runnable task) { return task; } ContextContinuation continuation = captureActiveSpan(); - if (continuation != noopContinuation()) { + if (continuation.context() != Context.root()) { return new JettyRunnableWrapper(task, continuation); } return task; // don't wrap unless there is a scope to propagate diff --git a/dd-java-agent/instrumentation/mongo/mongo-driver/mongo-driver-4.0/src/main/java/datadog/trace/instrumentation/mongo/CallbackWrapper.java b/dd-java-agent/instrumentation/mongo/mongo-driver/mongo-driver-4.0/src/main/java/datadog/trace/instrumentation/mongo/CallbackWrapper.java index 208f5aad8fd..118ce639074 100644 --- a/dd-java-agent/instrumentation/mongo/mongo-driver/mongo-driver-4.0/src/main/java/datadog/trace/instrumentation/mongo/CallbackWrapper.java +++ b/dd-java-agent/instrumentation/mongo/mongo-driver/mongo-driver-4.0/src/main/java/datadog/trace/instrumentation/mongo/CallbackWrapper.java @@ -1,9 +1,9 @@ package datadog.trace.instrumentation.mongo; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; import com.mongodb.internal.async.SingleResultCallback; +import datadog.context.Context; import datadog.context.ContextContinuation; import datadog.context.ContextScope; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; @@ -56,7 +56,7 @@ private ContextContinuation getAndResetContinuation() { public static SingleResultCallback wrapIfRequired(SingleResultCallback callback) { ContextContinuation continuation = captureActiveSpan(); - if (continuation != noopContinuation()) { + if (continuation.context() != Context.root()) { return new CallbackWrapper<>(continuation, callback); } return callback; diff --git a/dd-java-agent/instrumentation/netty/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java b/dd-java-agent/instrumentation/netty/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java index 654458b6c78..5daa04a82f5 100644 --- a/dd-java-agent/instrumentation/netty/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java +++ b/dd-java-agent/instrumentation/netty/netty-3.8/src/main/java/datadog/trace/instrumentation/netty38/NettyChannelInstrumentation.java @@ -3,7 +3,7 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.implementsInterface; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.rootContext; import static datadog.trace.instrumentation.netty38.NettyChannelPipelineInstrumentation.ADDITIONAL_INSTRUMENTATION_NAMES; import static datadog.trace.instrumentation.netty38.NettyChannelPipelineInstrumentation.INSTRUMENTATION_NAME; import static net.bytebuddy.matcher.ElementMatchers.isMethod; @@ -67,7 +67,7 @@ public static class ChannelConnectAdvice extends AbstractNettyAdvice { @Advice.OnMethodEnter public static void addConnectContinuation(@Advice.This final Channel channel) { ContextContinuation continuation = captureActiveSpan(); - if (continuation != noopContinuation()) { + if (continuation.context() != rootContext()) { final ContextStore contextStore = InstrumentationContext.get(Channel.class, ChannelTraceContext.class); diff --git a/dd-java-agent/instrumentation/netty/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java index 9f3468fc471..d2f514c08bb 100644 --- a/dd-java-agent/instrumentation/netty/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java @@ -5,7 +5,7 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.rootContext; import static datadog.trace.instrumentation.netty40.AttributeKeys.CONNECT_PARENT_CONTINUATION_ATTRIBUTE_KEY; import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.returns; @@ -232,7 +232,7 @@ public static class ConnectAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void addParentSpan(@Advice.This final ChannelPipeline pipeline) { ContextContinuation continuation = captureActiveSpan(); - if (continuation != noopContinuation()) { + if (continuation.context() != rootContext()) { final Attribute attribute = pipeline.channel().attr(CONNECT_PARENT_CONTINUATION_ATTRIBUTE_KEY); if (!attribute.compareAndSet(null, continuation)) { diff --git a/dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java index 8bdaa0bfd65..a1ceb822132 100644 --- a/dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java @@ -5,7 +5,7 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.rootContext; import static datadog.trace.instrumentation.netty41.AttributeKeys.CONNECT_PARENT_CONTINUATION_ATTRIBUTE_KEY; import static datadog.trace.instrumentation.netty41.AttributeKeys.HTTP2_CONNECTION_CODEC_ATTRIBUTE_KEY; import static net.bytebuddy.matcher.ElementMatchers.isMethod; @@ -257,7 +257,7 @@ public static class ConnectAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static boolean addParentSpan(@Advice.This final ChannelPipeline pipeline) { ContextContinuation continuation = captureActiveSpan(); - if (continuation != noopContinuation()) { + if (continuation.context() != rootContext()) { final Attribute attribute = pipeline.channel().attr(CONNECT_PARENT_CONTINUATION_ATTRIBUTE_KEY); if (!attribute.compareAndSet(null, continuation)) { diff --git a/dd-java-agent/instrumentation/netty/netty-promise-4.0/src/main/java/datadog/trace/instrumentation/netty4/promise/ListenerWrapper.java b/dd-java-agent/instrumentation/netty/netty-promise-4.0/src/main/java/datadog/trace/instrumentation/netty4/promise/ListenerWrapper.java index 8c74d532f23..3b2d2ee4a8e 100644 --- a/dd-java-agent/instrumentation/netty/netty-promise-4.0/src/main/java/datadog/trace/instrumentation/netty4/promise/ListenerWrapper.java +++ b/dd-java-agent/instrumentation/netty/netty-promise-4.0/src/main/java/datadog/trace/instrumentation/netty4/promise/ListenerWrapper.java @@ -1,8 +1,8 @@ package datadog.trace.instrumentation.netty4.promise; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; +import datadog.context.Context; import datadog.context.ContextContinuation; import datadog.context.ContextScope; import io.netty.util.concurrent.Future; @@ -17,7 +17,7 @@ public static GenericFutureListener wrapIfNeeded(final GenericFutureListener lis return listener; } ContextContinuation continuation = captureActiveSpan(); - if (continuation == noopContinuation()) { + if (continuation.context() == Context.root()) { return listener; } if (listener instanceof GenericProgressiveFutureListener) { diff --git a/dd-java-agent/instrumentation/opentracing/opentracing-0.31/src/test/groovy/OpenTracing31Test.groovy b/dd-java-agent/instrumentation/opentracing/opentracing-0.31/src/test/groovy/OpenTracing31Test.groovy index 8080a809009..e1318ae4d45 100644 --- a/dd-java-agent/instrumentation/opentracing/opentracing-0.31/src/test/groovy/OpenTracing31Test.groovy +++ b/dd-java-agent/instrumentation/opentracing/opentracing-0.31/src/test/groovy/OpenTracing31Test.groovy @@ -1,3 +1,4 @@ +import datadog.context.Context import datadog.trace.agent.test.InstrumentationSpecification import datadog.trace.api.DDSpanId import datadog.trace.api.DDTags @@ -28,7 +29,6 @@ import io.opentracing.util.GlobalTracer import spock.lang.Subject import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation class OpenTracing31Test extends InstrumentationSpecification { @@ -165,7 +165,7 @@ class OpenTracing31Test extends InstrumentationSpecification { span instanceof MutableSpan scope instanceof TraceScope !internalTracer.isAsyncPropagationEnabled() - (scope as TraceScope).capture() == noopContinuation() + (scope as TraceScope).capture().context() == Context.root() (tracer.scopeManager().active().span().delegate == span.delegate) when: diff --git a/dd-java-agent/instrumentation/opentracing/opentracing-0.32/src/test/groovy/OpenTracing32Test.groovy b/dd-java-agent/instrumentation/opentracing/opentracing-0.32/src/test/groovy/OpenTracing32Test.groovy index 99aaddfe1e0..c02f3a5b71c 100644 --- a/dd-java-agent/instrumentation/opentracing/opentracing-0.32/src/test/groovy/OpenTracing32Test.groovy +++ b/dd-java-agent/instrumentation/opentracing/opentracing-0.32/src/test/groovy/OpenTracing32Test.groovy @@ -1,3 +1,4 @@ +import datadog.context.Context import datadog.trace.agent.test.InstrumentationSpecification import datadog.trace.api.DDSpanId import datadog.trace.api.DDTags @@ -34,7 +35,6 @@ import static datadog.trace.api.sampling.PrioritySampling.USER_KEEP import static datadog.trace.api.sampling.SamplingMechanism.AGENT_RATE import static datadog.trace.api.sampling.SamplingMechanism.DEFAULT import static datadog.trace.api.sampling.SamplingMechanism.MANUAL -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation class OpenTracing32Test extends InstrumentationSpecification { @@ -176,7 +176,7 @@ class OpenTracing32Test extends InstrumentationSpecification { span instanceof MutableSpan scope instanceof TraceScope !internalTracer.isAsyncPropagationEnabled() - (scope as TraceScope).capture() == noopContinuation() + (scope as TraceScope).capture().context() == Context.root() (tracer.scopeManager().active().span().delegate == span.delegate) when: diff --git a/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/main/java/datadog/trace/instrumentation/springscheduling/SpannedMethodInvocation.java b/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/main/java/datadog/trace/instrumentation/springscheduling/SpannedMethodInvocation.java index 5677ea2bccf..2b713ef8500 100644 --- a/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/main/java/datadog/trace/instrumentation/springscheduling/SpannedMethodInvocation.java +++ b/dd-java-agent/instrumentation/spring/spring-scheduling-3.1/src/main/java/datadog/trace/instrumentation/springscheduling/SpannedMethodInvocation.java @@ -1,10 +1,10 @@ package datadog.trace.instrumentation.springscheduling; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.instrumentation.springscheduling.SpringSchedulingDecorator.DECORATE; +import datadog.context.Context; import datadog.context.ContextContinuation; import datadog.context.ContextScope; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; @@ -35,7 +35,7 @@ public Object[] getArguments() { @Override public Object proceed() throws Throwable { CharSequence spanName = DECORATE.spanNameForMethod(delegate.getMethod()); - if (continuation != noopContinuation()) { + if (continuation.context() != Context.root()) { return invokeWithContinuation(spanName); } else { return invokeWithSpan(spanName); diff --git a/dd-java-agent/instrumentation/synapse-3.0/src/main/java/datadog/trace/instrumentation/synapse3/SynapseClientWorkerInstrumentation.java b/dd-java-agent/instrumentation/synapse-3.0/src/main/java/datadog/trace/instrumentation/synapse3/SynapseClientWorkerInstrumentation.java index b377eb7a006..76e0ff7d8e4 100644 --- a/dd-java-agent/instrumentation/synapse-3.0/src/main/java/datadog/trace/instrumentation/synapse3/SynapseClientWorkerInstrumentation.java +++ b/dd-java-agent/instrumentation/synapse-3.0/src/main/java/datadog/trace/instrumentation/synapse3/SynapseClientWorkerInstrumentation.java @@ -2,7 +2,7 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.rootContext; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.instrumentation.synapse3.SynapseClientDecorator.DECORATE; import static datadog.trace.instrumentation.synapse3.SynapseClientDecorator.SYNAPSE_CONTINUATION_KEY; @@ -56,7 +56,7 @@ public static final class NewClientWorkerAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void createWorker(@Advice.Argument(2) final TargetResponse response) { ContextContinuation continuation = captureActiveSpan(); - if (continuation != noopContinuation()) { + if (continuation.context() != rootContext()) { response.getConnection().getContext().setAttribute(SYNAPSE_CONTINUATION_KEY, continuation); } } diff --git a/dd-java-agent/instrumentation/synapse-3.0/src/main/java/datadog/trace/instrumentation/synapse3/SynapseServerWorkerInstrumentation.java b/dd-java-agent/instrumentation/synapse-3.0/src/main/java/datadog/trace/instrumentation/synapse3/SynapseServerWorkerInstrumentation.java index 626e76e9b6f..292c62038d0 100644 --- a/dd-java-agent/instrumentation/synapse-3.0/src/main/java/datadog/trace/instrumentation/synapse3/SynapseServerWorkerInstrumentation.java +++ b/dd-java-agent/instrumentation/synapse-3.0/src/main/java/datadog/trace/instrumentation/synapse3/SynapseServerWorkerInstrumentation.java @@ -2,7 +2,7 @@ import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; +import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.rootContext; import static datadog.trace.bootstrap.instrumentation.api.Java8BytecodeBridge.spanFromContext; import static datadog.trace.instrumentation.synapse3.SynapseServerDecorator.DECORATE; import static datadog.trace.instrumentation.synapse3.SynapseServerDecorator.SYNAPSE_CONTEXT_KEY; @@ -60,7 +60,7 @@ public static final class NewServerWorkerAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void createWorker(@Advice.Argument(0) final SourceRequest request) { ContextContinuation continuation = captureActiveSpan(); - if (continuation != noopContinuation()) { + if (continuation.context() != rootContext()) { request.getConnection().getContext().setAttribute(SYNAPSE_CONTINUATION_KEY, continuation); } } diff --git a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/UndertowRunnableWrapper.java b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/UndertowRunnableWrapper.java index 826542fc102..e68b7a6e9a1 100644 --- a/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/UndertowRunnableWrapper.java +++ b/dd-java-agent/instrumentation/undertow/undertow-2.0/src/main/java/datadog/trace/instrumentation/undertow/UndertowRunnableWrapper.java @@ -1,10 +1,10 @@ package datadog.trace.instrumentation.undertow; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; import static datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter.ExcludeType.RUNNABLE; import static datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter.exclude; +import datadog.context.Context; import datadog.context.ContextContinuation; import datadog.context.ContextScope; import io.undertow.server.HttpServerExchange; @@ -34,7 +34,7 @@ public static Runnable wrapIfNeeded(final Runnable task, HttpServerExchange exch return task; } ContextContinuation continuation = captureActiveSpan(); - if (continuation != noopContinuation()) { + if (continuation.context() != Context.root()) { return new UndertowRunnableWrapper(task, exchange, continuation); } return task; // don't wrap unless there is a span to propagate diff --git a/dd-trace-core/src/main/java/datadog/trace/core/scopemanager/ContinuableScopeManager.java b/dd-trace-core/src/main/java/datadog/trace/core/scopemanager/ContinuableScopeManager.java index e91360316b4..399ac55e528 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/scopemanager/ContinuableScopeManager.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/scopemanager/ContinuableScopeManager.java @@ -24,6 +24,7 @@ import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTraceCollector; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; +import datadog.trace.bootstrap.instrumentation.api.NoopContinuation; import datadog.trace.bootstrap.instrumentation.api.ProfilerContext; import datadog.trace.bootstrap.instrumentation.api.ProfilingContextIntegration; import datadog.trace.core.monitor.HealthMetrics; @@ -49,6 +50,9 @@ public final class ContinuableScopeManager { static final Logger log = LoggerFactory.getLogger(ContinuableScopeManager.class); static final RatelimitedLogger ratelimitedLog = new RatelimitedLogger(log, 1, MINUTES); + + private static final NoopContinuation ROOT_CONTINUATION = NoopContinuation.INSTANCE; + static final long iterationKeepAlive = SECONDS.toMillis(Config.get().getScopeIterationKeepAlive()); volatile ConcurrentMap rootIterationScopes; @@ -112,7 +116,7 @@ public AgentScope.Continuation captureActiveSpan() { return captureSpan(activeScope.context, activeScope.source(), span); } } - return AgentTracer.noopContinuation(); + return ROOT_CONTINUATION; } public ContextContinuation captureSpan(final AgentSpan span) { @@ -408,12 +412,16 @@ public Context swap(@NonNull Context context) { } public ContextContinuation capture(@NonNull Context context) { + if (context == Context.root()) { + return ROOT_CONTINUATION; + } + // respect async propagation flag for Context.current().capture() ContinuableScope activeScope = scopeStack().active(); if (activeScope != null - && activeScope.context == context - && !activeScope.isAsyncPropagating()) { - return AgentTracer.noopContinuation(); + && !activeScope.isAsyncPropagating() + && activeScope.context == context) { + return ROOT_CONTINUATION; } AgentSpan span = AgentSpan.fromContext(context); AgentTraceCollector traceCollector; diff --git a/dd-trace-core/src/test/java/datadog/trace/core/scopemanager/ScopeManagerForkedTest.java b/dd-trace-core/src/test/java/datadog/trace/core/scopemanager/ScopeManagerForkedTest.java index 1340683a44e..440259d85b6 100644 --- a/dd-trace-core/src/test/java/datadog/trace/core/scopemanager/ScopeManagerForkedTest.java +++ b/dd-trace-core/src/test/java/datadog/trace/core/scopemanager/ScopeManagerForkedTest.java @@ -1,6 +1,5 @@ package datadog.trace.core.scopemanager; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopSpan; import static datadog.trace.core.scopemanager.ScopeManagerForkedTest.EVENT.ACTIVATE; import static datadog.trace.core.scopemanager.ScopeManagerForkedTest.EVENT.CLOSE; @@ -205,12 +204,12 @@ void ddScopeCreatesNoOpContinuationsWhenPropagationIsNotSet() { tracer.setAsyncPropagationEnabled(false); ContextContinuation continuation = tracer.captureActiveSpan(); - assertSame(noopContinuation(), continuation); + assertSame(Context.root(), continuation.context()); tracer.setAsyncPropagationEnabled(true); continuation = tracer.captureActiveSpan(); - assertNotSame(noopContinuation(), continuation); + assertNotSame(Context.root(), continuation.context()); assertNotNull(continuation); continuation.release(); diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java index 826dc5b9aa6..237ea38267f 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/AgentTracer.java @@ -236,19 +236,6 @@ public static AgentScope noopScope() { return NoopScope.INSTANCE; } - /** - * Returns the noop continuation instance. - * - *

This instance will always be the same, and can be safely tested using object identity (ie - * {@code ==}). - * - * @return the noop continuation instance. - */ - @SuppressWarnings("deprecation") - public static AgentScope.Continuation noopContinuation() { - return NoopContinuation.INSTANCE; - } - public static final TracerAPI NOOP_TRACER = new NoopTracerAPI(); private static volatile TracerAPI provider = NOOP_TRACER; @@ -693,7 +680,7 @@ public Context swap(Context context) { @Override public ContextContinuation capture(Context context) { - return noopContinuation(); + return NoopContinuation.INSTANCE; } } diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/NoopContinuation.java b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/NoopContinuation.java index 633a053585e..bc3640608c2 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/NoopContinuation.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/NoopContinuation.java @@ -4,8 +4,8 @@ import datadog.context.ContextScope; @SuppressWarnings("deprecation") -final class NoopContinuation implements AgentScope.Continuation { - static final NoopContinuation INSTANCE = new NoopContinuation(); +public final class NoopContinuation implements AgentScope.Continuation { + public static final NoopContinuation INSTANCE = new NoopContinuation(); private NoopContinuation() {} @@ -21,7 +21,7 @@ public ContextScope resume() { @Override public Context context() { - return NoopSpan.INSTANCE; + return Context.root(); } @Override diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/java/lang/ProcessImplInstrumentationHelpers.java b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/java/lang/ProcessImplInstrumentationHelpers.java index 334675c7e4e..1e63487012a 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/java/lang/ProcessImplInstrumentationHelpers.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/java/lang/ProcessImplInstrumentationHelpers.java @@ -2,10 +2,10 @@ import static datadog.trace.api.gateway.Events.EVENTS; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.captureActiveSpan; -import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.noopContinuation; import static java.lang.invoke.MethodType.methodType; import datadog.appsec.api.blocking.BlockingException; +import datadog.context.Context; import datadog.context.ContextContinuation; import datadog.context.ContextScope; import datadog.trace.api.Config; @@ -310,7 +310,7 @@ public static void shiRaspCheck(@Nonnull final String cmd) { private static void finishSpan( final ContextContinuation parentContinuation, final AgentSpan span) { - if (parentContinuation == noopContinuation()) { + if (parentContinuation.context() == Context.root()) { span.finish(); return; }