[ 
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)

Reply via email to