shashank created CAMEL-25002:
--------------------------------

             Summary: Loop EIP: a negative or very large loop count makes 
graceful shutdown stop without waiting for inflight exchanges
                 Key: CAMEL-25002
                 URL: https://issues.apache.org/jira/browse/CAMEL-25002
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: shashank


{{LoopProcessor}} adds the evaluated loop count to its pending task counter 
without checking the sign ({{taskCount.add(count)}}). A count of zero or less 
runs no iteration, and nothing removes a negative add again. After a single 
message with, for example, {{loop(header("n"))}} and {{n=-1}}, 
{{getPendingExchangesSize()}} returns -1 for the rest of the route's life.

{{DefaultShutdownStrategy}} adds the pending sizes of the route's services to 
the inflight count (in {{int}}) and waits only while the sum is positive. The 
same {{LoopProcessor}} is a child of several route services and is counted once 
for each of them. The negative value therefore cancels real inflight exchanges: 
a graceful stop returns immediately, and the inflight exchange fails with a 
{{RejectedExecutionException}}. A very large loop count (from about 2^29) has 
the same effect, because the {{int}} sum overflows.

With {{breakOnShutdown}}, a loop that breaks out leaves its remaining 
iterations pending, so every later shutdown waits for its full timeout 
({{LoopBreakOnShutdownTest}} takes about 10 s because of this).

Observed: after one message with {{n=-1}}, stopping the route takes 0 ms 
instead of waiting for the inflight exchange, which then fails with 
{{RejectedExecutionException}}. With {{n=0}} or {{n=2}}, the stop waits and the 
exchange completes.

History: CAMEL-15578 clamped the gap with {{Math.max(count - index, 0)}}. 
CAMEL-16794 switched to a {{LongAdder}} with an unconditional {{add(count)}} 
and dropped the clamp. CAMEL-19738 added the per-iteration decrement for the 
early-exit case only. CAMEL-18713 fixed a similar symptom for {{loopDoWhile}}.

Proposed fix: only add a positive count, release the iterations left exactly 
once whenever the loop ends (normally, on an exception, or when it breaks on 
shutdown), and in {{DefaultShutdownStrategy}} sum the pending sizes as a 
{{long}}, ignore negative sizes and cap the result. A PR with regression tests 
follows.

Found with a Lean 4 model of the pending-count arithmetic, then reproduced 
against the real classes.



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

Reply via email to