Repository navigation
Description
Is your feature request related to a problem? Please describe.
When incorporating openfeign and circuitbreaker in a spring-boot project, our code submits tasks to the executorService for execution. The executorService is created using Executors.newCachedThreadPool(). We intend to customize this thread pool to propagate ThreadLocal information from the main thread to the child threads.
While the Resilience4JCircuitBreakerFactory#configureExecutorService method allows reconfiguration of the thread pool, the groupExecutorService is hard-coded in the code and lacks extensibility, making it challenging to fully implement the desired functionality.
Describe the solution you'd like
We propose making the groupExecutorService customizable or providing a mechanism for extension so that developers can seamlessly implement customizations to pass ThreadLocal information to the child threads.
Additional Information:
Code Reference: Resilience4JCircuitBreakerFactory#configureExecutorService
Current Limitation: Inability to customize groupExecutorService for complete functionality implementation.
Expected Outcome:
We request enhancements to the Resilience4J CircuitBreakerFactory to allow developers to easily customize the groupExecutorService or provide an extension mechanism to fulfill the requirement of passing ThreadLocal information to child threads.
Sample codeοΌ
@Configurable
@AllArgsConstructor
public class CircuitBreakerConfiguration implements ApplicationRunner {
private final Resilience4JCircuitBreakerFactory factory;
@Override
public void run(ApplicationArguments args) throws Exception {
ContextThreadPoolExecutor contextThreadPoolExecutor =
new ContextThreadPoolExecutor(2, 5, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(1024));
// **change ThreadPoolExecutor**
factory.configureExecutorService(contextThreadPoolExecutor);
}
public static class ContextThreadPoolExecutor extends ThreadPoolExecutor {
public ContextThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
public void execute(Runnable command) {
super.execute(wrap(command));
}
private static Runnable wrap(Runnable runnable) {
**SubjectContext context = SubjectContext.getContext();**
return () -> {
**SubjectContext.setContext(context);**
try {
runnable.run();
} finally {
**SubjectContext.clear();**
}
};
}
}
}@Override
public org.springframework.cloud.client.circuitbreaker.CircuitBreaker create(String id) {
Assert.hasText(id, "A CircuitBreaker must have an id.");
Resilience4JCircuitBreaker resilience4JCircuitBreaker = create(id, id, this.executorService);
return tryObservedCircuitBreaker(resilience4JCircuitBreaker);
}
@Override
public org.springframework.cloud.client.circuitbreaker.CircuitBreaker create(String id, String groupName) {
Assert.hasText(id, "A CircuitBreaker must have an id.");
Assert.hasText(groupName, "A CircuitBreaker must have a group name.");
// **Fixed thread pool creation method, unable to expand**
final ExecutorService groupExecutorService = executorServices.computeIfAbsent(groupName,
group -> Executors.newCachedThreadPool());
Resilience4JCircuitBreaker resilience4JCircuitBreaker = create(id, groupName, groupExecutorService);
return tryObservedCircuitBreaker(resilience4JCircuitBreaker);
}Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
- StatusShow more project fieldsDone
Activity
ryanjbaxter commentedon Dec 7, 2023
Would you be interested in submitting a PR for this?
Customizable groupExecutorService spring-cloud#180
imyzt commentedon Dec 10, 2023
@ryanjbaxter Of course, Please read my code to ensure it can run in any scenario. #181
Thanks.
Customizable groupExecutorService spring-cloud#180
Merge pull request #181 from imyzt/main
yong-kurly commentedon Mar 6, 2024
@ryanjbaxter
I think this patch should be applied in
3.1.xas well.ryanjbaxter commentedon Mar 6, 2024
@yong-kurly it was see 5fa638e
yong-kurly commentedon Mar 6, 2024
Ah! Sorry.
3.1.1version has not been released, so I though it was not.I'm looking forward 3.1.1 release!
yong-kurly commentedon Mar 27, 2024
Just curious: May I know when the new version(3.1.x) will be released? I am waiting for this feature. π
ryanjbaxter commentedon Mar 27, 2024
This week.