shashank created CAMEL-26633:
--------------------------------
Summary: camel-core - Loop EIP with breakOnShutdown stops looping
for good after its route was suspended, or stopped and started
Key: CAMEL-26633
URL: https://issues.apache.org/jira/browse/CAMEL-26633
Project: Camel
Issue Type: Bug
Components: camel-core
Reporter: shashank
Assignee: shashank
Found during a Fray (controlled concurrency testing for the JVM) hunt on route
stop and start, while reading the shutdown hooks of the EIPs; no race is
needed, the order alone is enough.
{{LoopProcessor.prepareShutdown}} sets {{shutdownPending = true}} and nothing
ever clears it. The shutdown strategy calls {{prepareShutdown}} when a route is
stopped and also when it is only suspended ({{suspendOnly=true}}). With
{{breakOnShutdown}} the loop checks {{shutdownPending && breakOnShutdown}}
before each iteration, so once the route was suspended and resumed, or stopped
and started again, every later exchange goes through the loop without a single
iteration, silently (no exception, no log):
{code:java}
from("direct:start").routeId("loop")
.loop(3).breakOnShutdown()
.to("mock:iteration")
.end()
.to("mock:result");
template.sendBody("direct:start", "a"); // 3 iterations
controller.stopRoute("loop");
controller.startRoute("loop"); // or suspendRoute + resumeRoute,
or CamelContext suspend + resume
template.sendBody("direct:start", "b"); // 0 iterations, mock:result still
gets "b"
{code}
Ways to get there: JMX / dev console / control bus / CLI stop + start or
suspend + resume of a route, route policies that stop and start or suspend and
resume a route, a CamelContext suspend + resume. The field is also a plain
field written by the shutdown thread and read by the routing threads.
The error handlers have the same kind of flag and clear it:
{{RedeliveryErrorHandler.preparingShutdown}} is ignored for a suspend and reset
in {{doStart}} / {{doResume}}.
Expected: the loop breaks out only while its route (or the CamelContext) is
being stopped, and loops again after a restart. A suspend is not a shutdown
(the route is resumed later without being started again).
Suggested fix: like the error handlers, ignore
{{prepareShutdown(suspendOnly=true)}}, reset the flag in {{doStart}}, and make
it volatile.
Not covered by that: a suspend that times out forces the shutdown
({{prepareShutdown(false, true)}}), which stops the route consumer; a resume
does not start that consumer again, so such a route needs a stop and start
anyway (which clears the flag).
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)