You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (Jira)" <ji...@apache.org> on 2026/07/20 16:15:00 UTC

[jira] [Commented] (CAMEL-24137) Circuit Breaker EIP - modernization umbrella (drop vavr, async completion, virtual threads, duration units, breaker events)

    [ https://issues.apache.org/jira/browse/CAMEL-24137?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18097599#comment-18097599 ] 

Claus Ibsen commented on CAMEL-24137:
-------------------------------------

h3. Z3 — Virtual Threads: Already Supported (No Code Changes Needed)

Investigation shows the circuit breaker timeout executor already gets virtual threads transparently when the global setting is enabled:

* {{ResilienceReifier}} creates the executor via {{camelContext.getExecutorServiceManager().newThreadPool()}} — the standard Camel path
* {{CamelThreadFactory}} (MR-JAR, JDK 21 variant) creates virtual threads when {{camel.main.virtualThreadsEnabled=true}}
* {{DefaultThreadPoolFactory}} detects the virtual factory and uses {{Executors.newThreadPerTaskExecutor()}} instead of a fixed pool

This works because Camel's virtual thread support is at the factory level, not per-EIP. Every EIP (multicast, wire-tap, circuit breaker) uses {{ExecutorServiceManager}} and gets virtual threads automatically. No EIP contains direct {{ThreadType}} references.

If per-EIP virtual thread control were desired (e.g. {{resilience4jConfiguration().virtualThreads(true)}} independent of the global flag), that would need model + profile + factory changes (~5 files), but this seems unnecessary — the global setting covers it.

*Recommendation:* Consider Z3 done — already supported, no code changes needed.

_Claude Code on behalf of davsclaus_

> Circuit Breaker EIP - modernization umbrella (drop vavr, async completion, virtual threads, duration units, breaker events)
> ---------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-24137
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24137
>             Project: Camel
>          Issue Type: Improvement
>          Components: eip
>    Affects Versions: 4.21.0
>            Reporter: Federico Mariani
>            Assignee: Claus Ibsen
>            Priority: Major
>             Fix For: 4.22.0
>
>         Attachments: camel-circuitbreaker-eip-review-2026-07.md
>
>
> Umbrella for modernization suggestions from a review of the Circuit Breaker EIP (core model, camel-resilience4j, camel-microprofile-fault-tolerance). Full review document attached.
> h3. Z1. Drop Vavr from camel-resilience4j
> resilience4j 2.x removed its Vavr dependency, but camel-resilience4j re-adds {{vavr}} + {{vavr-match}} 1.0.0 solely for one {{Try.ofCallable(...).andThen(...).recover(...).get()}} chain in {{ResilienceProcessor.process()}}. A plain try/catch removes two runtime jars.
> h3. Z2. True async processing
> Both processors implement the async contract but are fully blocking: they always {{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 has CompletableFuture-based decorators and SmallRye supports async guard calls; completing the {{AsyncCallback}} from the worker would free consumer threads exactly when the breaker is protecting a slow downstream - the scenario the EIP exists for.
> h3. Z3. Virtual threads
> The timeout executor (resilience4j) and thread-offload executor (FT) are natural fits for virtual threads on JDK 21+ (Camel already has {{ThreadType}} support in the ExecutorServiceManager); this would make the thread-per-call model cheap even without Z2.
> h3. Z4. Unit/type consistency in the resilience4j configuration model
> {{waitDurationInOpenState}} and {{slowCallDurationThreshold}} are integer *seconds*, while {{timeoutDuration}} and {{bulkheadMaxWaitDuration}} are integer *millis*. The FT model already uses {{javaType=java.time.Duration}} with {{parseDuration}} (accepts {{5s}}, {{500ms}}). Migrating the resilience4j options to duration strings (with an upgrade-guide note) removes a recurring user trap.
> h3. Z5. Expose missing resilience4j 2.x features
> * {{maxWaitDurationInHalfOpenState}};
> * custom record/ignore predicate beans (currently only class-name lists);
> * referencing existing {{TimeLimiter}} / {{Bulkhead}} beans (only {{CircuitBreaker}} is referenceable today);
> * optional ThreadPoolBulkhead;
> * biggest observability win: bridge the resilience4j {{EventPublisher}} (state transitions, not-permitted calls) to Camel events / a RoutePolicy hook, so users do not have to poll JMX to learn the breaker opened.
> h3. Z6. Deprecate {{onFallbackViaNetwork}}
> Hystrix-era leftover; both remaining implementations throw {{UnsupportedOperationException}} at route init. The DSL method and model option exist only to fail.
> h3. Z7. Clarify {{micrometerEnabled}} scope
> It is only acted upon by camel-main's global {{detectResilience4jMicrometer}} (reading the *default* configuration); set inline on a route's {{resilience4jConfiguration}} it does nothing per-EIP. Document as global-only or wire it per-processor.
> h3. Z8. Test gaps
> No test asserts {{RESPONSE_TIMED_OUT}} in either module; no pooled-mode test with a consumer-created exchange (see CAMEL-24133); no test for fallback visibility of guard-level exception causes.
> _Filed by Claude Code on behalf of Federico Mariani (fmariani)_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)