spring-cloud-openfeign
spring-cloud-openfeign copied to clipboard
Request attributes exposed by circuit breakers are preserved permanently when called asynchronously
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();
}
}
};
mark
Hello, @vicasong. Thanks for reporting this. Makes sense. Would you like to create a PR with your proposed fix?
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.
PR created