Skip to content

Conversation

@JonasKunz
Copy link
Contributor

@JonasKunz JonasKunz commented Jun 26, 2023

What does this PR do?

Move the following responsibilites from Span to ElasticContext:

  • Creation of child spans
  • Context propagation

In addition to make plugins simpler I decided to ensure that ElasticContext is 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

@JonasKunz JonasKunz added the ci:agent-integration Enables agent integration tests in build pipeline label Jun 26, 2023
@ghost
Copy link

ghost commented Jun 26, 2023

💚 Build Succeeded

the below badges are clickable and redirect to their specific view in the CI or DOCS
Pipeline View Test View Changes Artifacts preview previewSnapshots

Expand to view the summary

Build stats

  • Start Time: 2023-07-03T11:39:14.976+0000

  • Duration: 14 min 53 sec

❕ Flaky test report

No test was executed to be analysed.

🤖 GitHub comments

Expand to view the GitHub comments

To re-run your PR in the CI, just comment with:

  • /test : Re-trigger the build.

  • run benchmark tests : Run the benchmark tests.

  • run jdk compatibility tests : Run the JDK Compatibility tests.

  • run integration tests : Run the Agent Integration tests.

  • run end-to-end tests : Run the APM-ITs.

  • run windows tests : Build & tests on windows.

  • run elasticsearch-ci/docs : Re-trigger the docs validation. (use unformatted text in the comment!)

return ((ElasticContextWrapper<?>) current).getWrappedContext();
}
return current;
return current != null ? current : EmptyElasticContext.INSTANCE;
Copy link
Contributor Author

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> {
Copy link
Contributor Author

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) {
Copy link
Contributor Author

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.

@JonasKunz JonasKunz marked this pull request as ready for review June 26, 2023 11:40
@JonasKunz JonasKunz requested a review from SylvainJuge June 26, 2023 11:40
@github-actions
Copy link

/test

return false;
}

context.incrementReferences();
Copy link
Member

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.

Copy link
Contributor Author

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) {
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

@SylvainJuge SylvainJuge left a 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 !!

JonasKunz added 5 commits July 3, 2023 10:53
# 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
@JonasKunz JonasKunz enabled auto-merge (squash) July 10, 2023 12:33
@JonasKunz JonasKunz merged commit 86184c5 into elastic:main Jul 10, 2023
@JonasKunz JonasKunz deleted the baggage-propagation branch July 10, 2023 14:06
JonasKunz added a commit to JonasKunz/apm-agent-java that referenced this pull request Jul 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-java ci:agent-integration Enables agent integration tests in build pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants