[
https://issues.apache.org/jira/browse/CAMEL-25014?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen resolved CAMEL-25014.
---------------------------------
Resolution: Fixed
Fixed by https://github.com/apache/camel/pull/26874 (merged to main for 4.23.0).
_Claude Code on behalf of davsclaus_
> ThrottlingExceptionRoutePolicy: since CAMEL-24903 the circuit stays open
> forever when the halfOpenHandler is not ready once, and keepOpen no longer
> suspends the consumer after a route restart
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25014
> URL: https://issues.apache.org/jira/browse/CAMEL-25014
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Reporter: shashank
> Priority: Minor
> Fix For: 4.23.0
>
>
> CAMEL-24903 (commit bd4d2ba20, PR #26799) added an early return to
> {{ThrottlingExceptionRoutePolicy.openCircuit}}
> ({{ThrottlingExceptionRoutePolicy.java:308-313}}):
> {code:java}
> if (state.get() == STATE_OPEN) {
> return;
> }
> {code}
> so that {{setKeepOpen(true)}} can call {{openCircuit}} safely. Two existing
> callers rely on {{openCircuit}} doing its work while the circuit is already
> OPEN:
> # {{calculateState}}, OPEN branch with a
> {{ThrottlingExceptionHalfOpenHandler}} ({{:273-280}}): when the handler says
> "not ready", {{openCircuit}} is called to re-arm the half-open timer. Now it
> returns at once: no timer is scheduled, the consumer stays suspended, so no
> exchange completes and {{calculateState}} is never called again. The first
> "not ready" answer suspends the route forever, although the handler is
> exactly meant to be asked again later.
> # {{onStart}} with {{keepOpen=true}} ({{:177-181}}): the policy is a
> CamelContext service, so its state survives {{stopRoute}}/{{startRoute}}.
> After a restart the state is still OPEN, {{openCircuit}} returns before
> suspending the newly started consumer, and the route consumes although
> keepOpen is set.
> *Reproduction* (file consumer, {{new ThrottlingExceptionRoutePolicy(1, 60000,
> 500, null)}}; the control runs use the class from before bd4d2ba20):
> {noformat}
> handler (halfOpenHandler: false on the 1st call, true afterwards; one failing
> file, then 3 good files)
> main: 3 s later: handlerCalls=1 circuit=opened consumer=Suspended
> goodProcessed=0/3 (same after 6 s)
> pre-24903: 3 s later: handlerCalls=2 circuit=closed consumer=Started
> goodProcessed=3/3
> keepopen (keepOpen=true; stopRoute + startRoute; 3 files dropped after the
> restart)
> main: circuit=opened consumer=Started consumed=3/3 (expected 0)
> pre-24903: circuit=opened consumer=Suspended consumed=0/3
> {noformat}
> TLA+: {{tep_handler}} violates {{NoStuckOpen}} (circuit OPEN, consumer
> suspended, no half-open timer, nothing inflight) in 4 states (Consume ->
> Done(failure) -> TimerFire(handler not ready)), {{tep_handler_live}} violates
> {{EventuallyClosed}}, {{tep_keepopen_restart}} violates {{KeepOpenHolds}}.
> The same configurations with the code before bd4d2ba20 hold.
> *Proposed fix:* keep the idempotent check in {{openCircuit}} (it was added in
> the CAMEL-24903 review so concurrent callers cannot stack half open timers),
> and add {{reopenCircuit}}, which suspends the consumer and schedules the next
> half open check also when the circuit is already open. Use it in the two
> places that must act on an open circuit: the half open handler "not ready"
> branch of {{calculateState}}, and {{onStart}} with {{keepOpen}}.
> {{addHalfOpenTimer}} replaces the previous timer under the lock and cancels
> it, and a half open task cancels only its own timer, so re-opening never
> leaves more than one timer thread.
> #26799 is labelled {{port/camel-4.22.x}}, so the same regression will reach
> 4.22.x when it is ported; the fix should be ported with it.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)