Problem: I have an @Async method, and when I call it, my current span is gone. The same happens when I execute tasks in a AsyncTaskExecutor.
Expectation: Trace propagation should work out of the box. Or there should be something easily findable in the documentation or in the configuration properties.
It looks like context propagation is not enabled for @Async methods. It took some time to find ContextPropagatingTaskDecorator. We don't have any mention on that in the Boot documentation, but Spring Framework's documentation briefly mentions it.
There's also no configuration property to enable that easily.
I'd like to have a ContextPropagatingTaskDecorator bean auto-configured. If that breaks stuff / make stuff slow, maybe behind a configuration property which is opt-in?
If that's not possible, we should add something to our Observability docs which can just hint at ContextPropagatingTaskDecorator.
@chemicL
Comment From: bclozel
This was handled in Spring Framework with https://github.com/spring-projects/spring-framework/issues/31130 and documented in the observability section.
Now applying such a decorator broadly will add overhead to many different tasks. I think the important part is whether we think the tradeoff is in favor of applying it and how.
Comment From: chemicL
I am wondering if "Application Events and @EventListener" section in the Spring Framework documentation is appropriate for @mhalbritter concern.
As I understand the application events or other types of events might in fact be decoupled from some processing that is handled by the app, e.g. in a controller, which naturally has an Observation that is associated with it.
However, here, specifically, the case is about an @Async method which is called from a controller. I am certain the code sample you shared with me, @mhalbritter, would highlight the issue very clearly. A controller method was delegating processing to two async methods in order to parallelize processing and then combined the result using the returned CompletableFuture's get() method. As a user, I would be puzzled as well if my trace information got lost in those asynchronous dispatches and would be in trouble as well without not knowing what to look for. A property in Spring Boot to enable automatic propagation (if enabling by default is out of the question) in such cases would come in handy. At least an easy way to find info about this situation.
A different subject is whether automatic propagation should be enabled or controlled globally for anything that uses the AsyncTaskExecutor. It can also be surprising if the user starts an Observation in an @EventListener method and delegates to an async task which loses the context, but that can be a separate subject to discuss.
Comment From: mhalbritter
This is the code @chemicL is talking about: https://github.com/mhalbritter/spring-boot-and-opentelemetry/blob/126d94bcd82441e540540cc25287226eca7cb097/hello-service/src/main/java/com/example/hello/HelloService.java#L52
Here's the async call happening: https://github.com/mhalbritter/spring-boot-and-opentelemetry/blob/126d94bcd82441e540540cc25287226eca7cb097/hello-service/src/main/java/com/example/hello/greeting/GreetingServiceClient.java#L31
This also doesn't work if you use an @Async method without registering a ContextPropagatingTaskDecorator.