shashank created CAMEL-24950:
--------------------------------
Summary: camel-seda - purging the queue leaves request/reply
producers waiting for exchanges that were discarded (forever with timeout=0)
Key: CAMEL-24950
URL: https://issues.apache.org/jira/browse/CAMEL-24950
Project: Camel
Issue Type: Bug
Components: camel-seda
Reporter: shashank
{{SedaEndpoint.purgeQueue()}} is just {{queue.clear()}}. It is called:
* from {{SedaConsumer.doStop()}} and from {{getPendingExchangesSize()}} when
{{purgeWhenStopping=true}};
* from the JMX operation.
A request/reply exchange sent with
{{waitForTaskToComplete=Always}}/{{IfReplyExpected}} is a copy whose {{onDone}}
synchronization counts down the producer's latch (SedaProducer.java:70-106).
The purge drops the copy without completing it, so the producer keeps waiting:
* with a timeout, it waits the full timeout and then gets
{{ExchangeTimedOutException}};
* with {{timeout=0}} (documented as "disable timeout"), it waits forever.
Reproduced against 4.23.0-SNAPSHOT: route
{{from("seda:svc?purgeWhenStopping=true")}} busy with one message, then a
request {{seda:svc?timeout=0}}, then {{stopRoute("svc")}}:
{noformat}
route 'svc' status: Stopped
3 s after the stop, requester thread state=WAITING in
SedaProducer.process(SedaProducer.java:142)
{noformat}
With {{timeout=6000}}, the requester returned {{ExchangeTimedOutException}}
after 6007 ms, although its request had been discarded about 1.5 s after it was
sent. The producer's own route cannot shut down gracefully while that thread
waits, because the exchange is still inflight there.
Proposed fix: when purging, drain the queue ({{drainTo}}) instead of
{{clear()}}, fail each discarded exchange with
{{RejectedExecutionException("Exchange discarded as the SEDA queue was
purged")}} and run its on completions
({{UnitOfWorkHelper.doneSynchronizations(exchange,
exchange.getExchangeExtension().handoverCompletions())}}, as {{SedaConsumer}}
does after a multicast). Waiting producers are released with that exception.
Behaviour change to call out: on completions handed over to a discarded InOnly
exchange (e.g. the file consumer's commit/rollback,
{{onCompletion().onFailureOnly()}}) now run as a failure, on the thread that
purges (shutdown task or JMX). Previously they never ran.
A PR with the fix follows, with regression test
{{SedaPurgeWhenStoppingWaitingProducerTest}} (stop with {{purgeWhenStopping}},
and a JMX-style {{purgeQueue()}}), plus an upgrade-guide note.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)