-
Notifications
You must be signed in to change notification settings - Fork 863
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
Thread locals are lost after the control is returned from SDK methods to the client code #5242
Comments
I've filed this one as a feature request and not a bug, as I wasn't sure if Thread Locals support was even considered initially. But the issue can be converted into a bug if you think it gives more clarity. OS version does not really matter, the issue presents on all OS that Java supports. It can also be observed on Java 11 and 21. |
@debora-ito Would you mind consider this issue for triage ? |
@scrocquesel Facing the same issue with a quarkus application. @Path("/exec")
@GET
@Produces(MediaType.TEXT_PLAIN)
public Uni<String> exec() {
MDC.put("mykey", "myvalue");
return
S3Utils
.getObject(s3Context) //returns Uni<ResponseBytes<GetObjectResponse>>
.invoke(() -> log.info("bug MDC : {}", MDC.get("mykey"))) //null
.chain(() -> Uni.createFrom().item("MDC fails"));
}
Adding : .asyncConfiguration(b -> b.advancedOption(SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR, executor)) //executor is Injected by CDI : @Inject ManagedExecutor executor` doesn't change anything :
Both sdk-async-response-13-0 and executor-thread-1 threads fail to propagate the MDC. The quarkus documentation supports it |
With quarkus and mutiny, see the pattern in this comment quarkiverse/quarkus-amazon-services#998 (comment). |
Thank you Im doing like this : @Path("/exec")
@GET
@Produces(MediaType.TEXT_PLAIN)
public Uni<String> exec() {
MDC.put("mykey", "myvalue");
//var context = VertxContext.getOrCreateDuplicatedContext();
var context = Vertx.currentContext();
return
S3Utils
.getObject(s3Context)
//.emitOn(r -> context.runOnContext(_ -> r.run()))
.emitOn(context::runOnContext)
.invoke(() -> log.info("fixing MDC : {}", MDC.get("mykey"))) //now ok :)
.chain(() -> Uni.createFrom().item("MDC fixed"));
} Are the two approaches the same? |
In this case yes. You'll always have a valid current context |
Describe the feature
This is pretty much a copy of this issue #2142 to be able to continue the discussion.
It's been closed for a while, so I guess it's not actively monitored anymore even though the issue still exists.
Basically the issue is that since aws sdk v2 uses netty nio, all thread locals are lost after any async sdk method is completed, that includes spring security context, mdc, servlet request attributes or anything else the developer might have put into a thread local. Unfortunately, there seems to be no way to tell the sdk to preserve this context or extend the sdk in a way that makes it possible. This makes it really hard to use aws sdk v2 in a spring web mvc environment without resorting to migrating to kotlin coroutines or some hacky workarounds (e.g. aspects).
Specifying SdkAdvancedAsyncClientOption.FUTURE_COMPLETION_EXECUTOR is also not a solution, since this executor is used after the control has returned from the netty thread pool so the context is already lost at this point.
Use Case
Logging and tracing in a Spring Web MVC environment. Trace and span ids are stored as MDC context (ThreadLocal variables). It's also common to put app-specific data into MDC context to be able to match log lines to a specific request. Currently, all this data are lost after any SDK call, so tracing essentially breaks after an AWS SDK call.
Proposed Solution
No response
Other Information
A shaky workaround I ended up using is to have an aspectj aspect around AWS SDK methods that adds a CompletableFuture handler that restores Thread Locals.
Acknowledgements
AWS Java SDK version used
2.25.43
JDK version used
17.0.6
Operating System and version
macOS Sonoma 14.5
The text was updated successfully, but these errors were encountered: