[
https://issues.apache.org/jira/browse/CAMEL-26605?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Work on CAMEL-26605 started by shashank.
----------------------------------------
> camel-seda - receive() without a timeout never returns after the
> CamelContext, the route of a pollEnrich or the consumer template stops
> ---------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26605
> URL: https://issues.apache.org/jira/browse/CAMEL-26605
> Project: Camel
> Issue Type: Bug
> Components: camel-seda
> Reporter: shashank
> Assignee: shashank
> Priority: Major
>
> Found while testing stop and receive orderings of the polling consumers, then
> reproduced with plain JUnit tests on the real classes.
> {{SedaPollingConsumer.receive()}} is {{getEndpoint().getQueue().take()}}. It
> does not look at the state of the polling consumer, so a thread that waits in
> it for a message waits for ever once nothing will put one there:
> * {{consumerTemplate.receive("seda:foo")}} / {{receiveBody("seda:foo")}} (no
> timeout) in a worker thread, then the CamelContext stops: the thread never
> returns. {{SedaComponent.doStop}} clears its queues, so after a restart of
> the CamelContext new messages go to a new queue and the thread waits on the
> old one for good (with a non-daemon thread the JVM does not exit).
> * {{consumerTemplate.stop()}} while a {{receive()}} waits: the same.
> * {{pollEnrich("seda:foo")}} with the default timeout (-1, which calls
> {{receive()}}): stopping the route or the CamelContext waits for the
> in-flight exchange until the shutdown timeout, the forced stop then stops the
> polling consumer, but the exchange thread stays in {{take()}} for ever.
> {{EventDrivenPollingConsumer}} (used by most other endpoints) checks
> {{isRunAllowed()}} every second while it waits, so it returns {{null}} in
> these cases (CAMEL-25036 made sure it can be stopped while it waits).
> CAMEL-25036 noted that seda has its own polling consumer and was not affected
> by that lock; this is the seda side of the same scenario.
> {code:java}
> // a worker thread
> Exchange exchange = consumerTemplate.receive("seda:idle"); // never returns
> after context.stop()
> // a route
> from("direct:start").pollEnrich("seda:idle").to("mock:result"); // the
> exchange thread never returns after stopRoute
> {code}
> Reproduction: a test that waits until the thread is inside
> {{SedaPollingConsumer.receive}}, then stops the CamelContext / the consumer
> template / the route (shutdown timeout 1 s), and waits 10 s for the call to
> return: all three time out on main. A control with a polling consumer that
> was never started still receives the next message.
> Expected: {{receive()}} returns {{null}} once the polling consumer is
> stopped, like {{EventDrivenPollingConsumer}}; a message already in the queue
> is still returned; a polling consumer that was never started keeps waiting
> (the current behaviour, which code that calls
> {{endpoint.createPollingConsumer().receive()}} without starting it may rely
> on).
> Suggested fix: wait with {{poll(1 s)}} in a loop and return {{null}} when the
> polling consumer is stopping, stopped or shut down (not when it was never
> started).
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)