[
https://issues.apache.org/jira/browse/CAMEL-24951?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen resolved CAMEL-24951.
---------------------------------
Fix Version/s: 4.23.0
Resolution: Fixed
The fix is merged on main, so it is in Camel 4.23.0:
* 210bcdeac8ed CAMEL-24951: camel-seda - do not wait for the pending messages
of a suspended consumer when stopping
* 0048a6264b9d CAMEL-24951: camel-seda - Keep waiting for the queue to be empty
when a starting consumer is stopped
* 1791c157b4cb CAMEL-24951: camel-seda - Make the suspended consumer test
deterministic
* 72284a0944d4 CAMEL-24951: camel-seda - Insert the upgrade guide section in
alphabetical order
* 9d8608ab4aed CAMEL-24951: camel-seda - Document the side effects of
SedaConsumer.getPendingExchangesSize
Resolving, as the ticket was not updated when the PR was merged.
_Claude Code on behalf of Claus Ibsen_
> Stopping a suspended SEDA route (or the CamelContext) with queued messages
> always waits for the full shutdown timeout
> ---------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24951
> URL: https://issues.apache.org/jira/browse/CAMEL-24951
> Project: Camel
> Issue Type: Bug
> Components: camel-core, camel-seda
> Reporter: shashank
> Priority: Minor
> Fix For: 4.23.0
>
>
> A suspended {{SedaConsumer}} does not poll, but graceful shutdown waits for
> it to drain its queue:
> * {{DefaultShutdownStrategy}} defers the seda consumer ({{deferShutdown}}
> returns true) and loops until inflight + {{getPendingExchangesSize()}} is 0.
> For seda, {{getPendingExchangesSize()}} is the queue size
> (DefaultShutdownStrategy.java:667-716, SedaConsumer.java:88-95).
> * After that, {{SedaConsumer.prepareShutdown}} waits on the poll threads'
> latch. The poll threads exit only when {{shutdownPending &&
> queue.isEmpty()}}, including in the suspended branch
> (SedaConsumer.java:175-191, :117).
> When the route is suspended and messages were sent to it in the meantime,
> neither wait can finish, so every stop runs into the timeout (default 45 s):
> * {{stopRoute(id)}} and {{camelContext.stop()}} take the full timeout and
> then force the shutdown.
> * {{stopRoute(id, timeout, unit, true)}} returns false and restarts the route.
> Reproduced against 4.23.0-SNAPSHOT, shutdown timeout 5 s, route
> {{from("seda:s")}} suspended with {{suspendRoute("s")}}:
> {noformat}
> stopRoute, route suspended, 0 queued : stop took 490 ms,
> timeoutOccurred=false
> stopRoute, route suspended, 3 queued : stop took 5002 ms,
> timeoutOccurred=true, left in queue=2
> context.stop, route suspended, 0 queued : stop took 507 ms,
> timeoutOccurred=false
> context.stop, route suspended, 3 queued : stop took 5005 ms,
> timeoutOccurred=true
> {noformat}
> During the forced stop the suspended route still processed one of the queued
> messages.
> CAMEL-6390 fixed stopping a suspended seda route with an empty queue. The
> queued-messages case is still open ({{SedaSuspendConsumerStopRouteTest}}
> stops with an empty queue). Routes suspended by a {{RoutePolicy}} such as
> {{ThrottlingInflightRoutePolicy}} end up in this state without user action,
> and route policies are not invoked while Camel is stopping, so they cannot
> resume the consumer either.
> Proposed fix: a suspended consumer cannot drain, so do not wait for it.
> * {{SedaConsumer.getPendingExchangesSize()}} returns 0 while the consumer is
> suspending or suspended (after the {{purgeWhenStopping}} purge, which is
> unchanged).
> * The suspended branch of {{doRun}} breaks out when {{shutdownPending}} is
> set, whether or not the queue is empty.
> The queued messages stay in the queue (or are purged by
> {{purgeWhenStopping}}) and are processed if the route is started again while
> the queue still exists. The stop completes in about one poll interval instead
> of the shutdown timeout, and the suspended route no longer processes a
> message during the forced stop.
> Design point for reviewers: the alternative is to drain, i.e. resume
> suspended seda consumers when stopping them. That would process messages on a
> route the user (or a {{RoutePolicy}}) suspended, and the route's own services
> are suspended too, so the patch keeps the messages instead. Today's outcome
> after the timeout is also "not drained", just 45 s later.
> A PR with the fix follows, with regression test
> {{SedaSuspendedRouteWithPendingStopTest}} ({{stopRoute}} with
> {{abortAfterTimeout=true}}, and {{context.stop()}}), plus an upgrade-guide
> note.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)