-
Notifications
You must be signed in to change notification settings - Fork 327
Context propagation refactorings #3206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Moved propagateContext from span to context
| return ((ElasticContextWrapper<?>) current).getWrappedContext(); | ||
| } | ||
| return current; | ||
| return current != null ? current : EmptyElasticContext.INSTANCE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change has been to simplify plugins: Instead of returning null when there is no context, we return an empty context. This avoids a lot of null-checks in the plugins.
If one really needs to know wheter a context is active or not, it is possible to do so by calling ElasticContext.isEmpty(). This is for example useful to optimize intra-process context propagation: No need to propagate empty contexts here.
|
|
||
| import javax.annotation.Nullable; | ||
|
|
||
| public interface ElasticContext<T extends ElasticContext<T>> extends ReferenceCounted, Activateable<T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ElasticContext is now reference counted. The reason is that context can reference spans and spans are reference counted.
E.g. if you were to propagate a context to another thread, you need to make sure to do an incrementReferenceCount on the context, just like we did for Spans until now.
|
|
||
| AbstractSpan<?> span = context.getSpan(); | ||
|
|
||
| if (activeContext != context && activeContext instanceof ElasticContextWrapper) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This unwrapping was unnecessary: currentContext has already been doing the unwrapping.
|
/test |
| return false; | ||
| } | ||
|
|
||
| context.incrementReferences(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here I am not sure why we increment references in the first place, but I think it's because the span reference is being used in the activation listeners, so might be worth checking if that does not mean systematically incrementing the context references count even when not needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do increment here to make sure that the Span (and now context) is not recycled while it is on the ActiveStack.
The same is now required for contexts, because we need to ensure that the underlying span is kept alive.
| } catch (Exception e) { | ||
| Span<?> span = null; | ||
| final ElasticContext<?> parent = TracerAwareInstrumentation.tracer.currentContext(); | ||
| if (parent.getSpan() != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpicking] keeping the shortcut return when there is no span avoids one level of if nesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, should have mentioned it in the PR description (updated it now):
This PR also changes that context propagation always happens, even if there is no active span.
E.g. if someone just updated the baggage, we want to still create baggage headers, even if no trace-context will be propagated. Baggage is conceptually independent from tracing.
For this reason I had to remove the early exits in order to make sure that the context propagation part is always reached.
...n/src/main/java/co/elastic/apm/agent/httpclient/v4/ApacheHttpAsyncClientInstrumentation.java
Outdated
Show resolved
Hide resolved
...n/src/main/java/co/elastic/apm/agent/httpclient/v4/ApacheHttpAsyncClientInstrumentation.java
Show resolved
Hide resolved
...plugin/src/main/java/co/elastic/apm/agent/httpclient/v4/ApacheHttpClientInstrumentation.java
Show resolved
Hide resolved
...plugin/src/main/java/co/elastic/apm/agent/httpclient/v4/ApacheHttpClientInstrumentation.java
Show resolved
Hide resolved
apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/ElasticContext.java
Show resolved
Hide resolved
.../src/main/java/co/elastic/apm/agent/httpclient/v4/LegacyApacheHttpClientInstrumentation.java
Outdated
Show resolved
Hide resolved
.../src/main/java/co/elastic/apm/agent/httpclient/v4/LegacyApacheHttpClientInstrumentation.java
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ActiveStack.java
Outdated
Show resolved
Hide resolved
apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/ElasticContext.java
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/EmptyElasticContext.java
Show resolved
Hide resolved
SylvainJuge
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I'm mostly nit-picking about minor style things, congrats on this huge refactor !!
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/AbstractSpan.java
Outdated
Show resolved
Hide resolved
...ent3-plugin/src/main/java/co/elastic/apm/agent/httpclient/v3/HttpClient3Instrumentation.java
Outdated
Show resolved
Hide resolved
...n/src/main/java/co/elastic/apm/agent/httpclient/v4/ApacheHttpAsyncClientInstrumentation.java
Outdated
Show resolved
Hide resolved
...plugin/src/main/java/co/elastic/apm/agent/httpclient/v4/ApacheHttpClientInstrumentation.java
Show resolved
Hide resolved
...c/test/java/co/elastic/apm/agent/httpclient/v4/ApacheHttpAsyncClientInstrumentationTest.java
Outdated
Show resolved
Hide resolved
...t-plugins/apm-struts-plugin/src/main/java/co/elastic/apm/agent/struts/ActionProxyAdvice.java
Outdated
Show resolved
Hide resolved
...t-plugins/apm-struts-plugin/src/main/java/co/elastic/apm/agent/struts/ActionProxyAdvice.java
Outdated
Show resolved
Hide resolved
...lugin/src/main/java/co/elastic/apm/agent/urlconnection/HttpUrlConnectionInstrumentation.java
Outdated
Show resolved
Hide resolved
.../apm-vertx-common/src/main/java/co/elastic/apm/agent/vertx/AbstractVertxWebClientHelper.java
Outdated
Show resolved
Hide resolved
...plugin/src/main/java/co/elastic/apm/agent/vertx/v4/webclient/HttpContextInstrumentation.java
Show resolved
Hide resolved
# Conflicts: # apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java # apm-agent-core/src/main/java/co/elastic/apm/agent/tracemethods/TraceMethodInstrumentation.java # apm-agent-plugins/apm-apache-httpclient/apm-apache-httpclient3-plugin/src/main/java/co/elastic/apm/agent/httpclient/v3/HttpClient3Instrumentation.java # apm-agent-plugins/apm-asynchttpclient-plugin/src/main/java/co/elastic/apm/agent/asynchttpclient/AbstractAsyncHttpClientInstrumentation.java # apm-agent-plugins/apm-aws-sdk/apm-aws-sdk-common/src/main/java/co/elastic/apm/agent/awssdk/common/AbstractSQSInstrumentationHelper.java # apm-agent-plugins/apm-dubbo-plugin/src/main/java/co/elastic/apm/agent/dubbo/advice/ApacheMonitorFilterAdvice.java # apm-agent-plugins/apm-es-restclient-plugin/apm-es-restclient-plugin-common/src/main/java/co/elastic/apm/agent/esrestclient/ElasticsearchRestClientInstrumentationHelper.java # apm-agent-plugins/apm-finagle-httpclient-plugin/src/main/java/co/elastic/apm/agent/finaglehttpclient/FinaglePayloadSizeFilterInstrumentation.java # apm-agent-plugins/apm-javalin-plugin/src/main/java/co/elastic/apm/agent/javalin/JavalinInstrumentation.java # apm-agent-plugins/apm-javalin-plugin/src/main/java/co/elastic/apm/agent/javalin/JavalinRenderInstrumentation.java # apm-agent-plugins/apm-jdbc-plugin/src/main/java/co/elastic/apm/agent/jdbc/helper/JdbcHelper.java # apm-agent-plugins/apm-jms-plugin/apm-jms-plugin-base/src/main/java/co/elastic/apm/agent/jms/JmsInstrumentationHelper.java # apm-agent-plugins/apm-jms-plugin/apm-jms-plugin-base/src/main/java/co/elastic/apm/agent/jms/JmsMessageConsumerInstrumentation.java # apm-agent-plugins/apm-servlet-plugin/src/main/java/co/elastic/apm/agent/servlet/ServletApiAdvice.java # apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/src/main/java/co/elastic/apm/agent/resttemplate/SpringRestTemplateAdvice.java # apm-agent-plugins/apm-spring-webflux/apm-spring-webclient-plugin/src/main/java/co/elastic/apm/agent/springwebclient/WebClientExchangeFunctionInstrumentation.java # apm-agent-plugins/apm-spring-webmvc/apm-spring-webmvc-spring5/src/main/java/co/elastic/apm/agent/springwebmvc/ViewRenderInstrumentation.java # apm-agent-plugins/apm-urlconnection-plugin/src/main/java/co/elastic/apm/agent/urlconnection/HttpUrlConnectionInstrumentation.java
What does this PR do?
Move the following responsibilites from
SpantoElasticContext:In addition to make plugins simpler I decided to ensure that
ElasticContextis never null by returning an empty context instead. This avoids a lot of null-checks in the plugins.Part of #3004 . This PR also changes that context propagation always happens, even if there is no active span.
E.g. if someone just updated the baggage, we want to still create baggage headers, even if no trace-context will be propagated.
This PR is a refactoring and should NOT change any actual functionality of the agent.
Checklist
I have updated CHANGELOG.asciidoc