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)

Reply via email to