Skip to content

Check jax-rs AsyncResponse for span before starting new one#1403

Merged
tylerbenson merged 3 commits into
masterfrom
tyler/jax-rs-nested-async
Apr 28, 2020
Merged

Check jax-rs AsyncResponse for span before starting new one#1403
tylerbenson merged 3 commits into
masterfrom
tyler/jax-rs-nested-async

Conversation

@tylerbenson

Copy link
Copy Markdown
Contributor

This will prevent the request from being broken due to replacing the unfinished span.

This will prevent the request from being broken due to replacing the unfinished span.
@tylerbenson tylerbenson requested a review from a team as a code owner April 27, 2020 20:49
final Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>();
transformers.put(
named("execute").and(takesArgument(0, Runnable.class)),
named("execute").and(takesArgument(0, Runnable.class)).and(takesArguments(1)),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not immediately related, though I discovered this problem in the same investigation and it is tangentially related...

When an executor has multiple execute methods, one calling the other, previously they were both instrumented and we would see Failed to set continuation because another continuation is already set log messages. This is because the first call would create a continuation, set it on the task, then call the next execute method, which would do the same, but it would close the second one and keep the first. These log messages were a red herring for my investigation as it didn't actually impact the application reporting.

Comment on lines +87 to +108
@Advice.This final Object target,
@Advice.Origin final Method method,
@Advice.AllArguments final Object[] args,
@Advice.Local("asyncResponse") AsyncResponse asyncResponse) {
ContextStore<AsyncResponse, AgentSpan> contextStore = null;
for (final Object arg : args) {
if (arg instanceof AsyncResponse) {
asyncResponse = (AsyncResponse) arg;
contextStore = InstrumentationContext.get(AsyncResponse.class, AgentSpan.class);
if (contextStore.get(asyncResponse) != null) {
/**
* We are probably in a recursive call and don't want to start a new span because it
* would replace the existing span in the asyncResponse and cause it to never finish. We
* could work around this by using a list instead, but we likely don't want the extra
* span anyway.
*/
return null;
}
break;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this doesn't need to be done for datadog.trace.instrumentation.jaxrs1.JaxRsAnnotationsInstrumentation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jaxrs1 doesn't support async. that is the main distinction between the two.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants