As shown in the code below, the request attributes are passed to the thread calling the execute method through the RequestContextHolder (ThreadLocal)
https://github.com/spring-cloud/spring-cloud-openfeign/blob/8493de9aa6038024acab81142c5cb714d1b9edfc/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignCircuitBreakerInvocationHandler.java#L124-L136
This code is from: https://github.com/spring-cloud/spring-cloud-openfeign/issues/193 And updated: https://github.com/spring-cloud/spring-cloud-openfeign/issues/572
This creates a conflict. The idea here should be to use ThreadLocal to pass request attributes in async calls and do nothing in sync calls. And now ThreadLocal is not cleaned up after using it in async call.
The easiest way is to compare whether the calling thread and the executing thread are consistent before the operation:
final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
final Thread caller = Thread.currentThread();
return () -> {
boolean isAsync = caller != Thread.currentThread();
try {
if (isAsync) {
RequestContextHolder.setRequestAttributes(requestAttributes);
}
return dispatch.get(method).invoke(args);
}
catch (RuntimeException throwable) {
throw throwable;
}
catch (Throwable throwable) {
throw new RuntimeException(throwable);
} finally {
if (isAsync) {
RequestContextHolder.resetRequestAttributes();
}
}
};
Comment From: mayben0t
mark
Comment From: OlgaMaciaszek
Hello, @vicasong. Thanks for reporting this. Makes sense. Would you like to create a PR with your proposed fix?
Comment From: spring-cloud-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: vicasong
PR created