Claus Ibsen created CAMEL-24209:
-----------------------------------
Summary: Circuit Breaker EIP - true async processing with
CompletionStage decorators
Key: CAMEL-24209
URL: https://issues.apache.org/jira/browse/CAMEL-24209
Project: Camel
Issue Type: Improvement
Components: eip
Reporter: Claus Ibsen
The resilience4j Circuit Breaker processor (ResilienceProcessor) implements the
async contract but is fully blocking: it always does callback.done(true);
return true, and the timeout path parks the calling thread on future.get()
while a second thread runs the work (two threads per in-flight message).
Resilience4j 2.x provides CompletionStage-based decorators for all three guards:
* CircuitBreaker.decorateCompletionStage() - fully non-blocking
* TimeLimiter.decorateCompletionStage(scheduler, supplier) - needs
ScheduledExecutorService
* Bulkhead.decorateCompletionStage() - non-blocking permit acquire/release
Using these would allow completing the AsyncCallback from the worker thread,
freeing consumer threads - the scenario the EIP exists for.
h3. Key challenges
# *Exchange copy lifecycle* - processTask() creates a correlated copy,
UnitOfWork, processes, copies results, and releases in a try/finally. In async
mode these must move into callback chains. Missed paths cause silent leaks.
# *Timeout race condition* - The AtomicBoolean exchangeWriteGuard prevents the
worker from writing results after timeout triggers fallback. With both sides
async, the race window widens.
# *Fallback restructuring* - CircuitBreakerFallbackTask implements
Function<Throwable, Exchange> for synchronous recovery. As a CompletionStage
error handler it returns a stage, not a value - the whole chain shape changes.
# *ScheduledExecutorService* - TimeLimiter.decorateCompletionStage() requires a
ScheduledExecutorService, not the plain ExecutorService currently configured.
Minor breaking change for users who pass a custom timeoutExecutorService bean.
# *Pooled task lifecycle* - acquire()/release() must move from try/finally to
completion callbacks.
h3. Value
Under high concurrency with timeout enabled, thread consumption drops from 2
blocked threads per exchange to 0. Most valuable for routes using async-capable
components (Netty HTTP, Kafka) where the framework can be fully non-blocking
end-to-end.
h3. Scope estimate
~300 lines production code (mostly ResilienceProcessor.java), ~20 lines in
ResilienceReifier.java, plus ~100-150 lines of new async-specific tests.
Medium-high risk due to exchange lifecycle and race condition handling.
See also umbrella issue CAMEL-24137 (Z2).
_Filed by Claude Code on behalf of davsclaus_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)