[
https://issues.apache.org/jira/browse/CAMEL-26601?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-26601:
--------------------------------
Fix Version/s: 4.24.0
> camel-core - Recipient list in a doTry: a producer that throws from
> process(exchange, callback), such as seda with a full queue, hangs the
> exchange
> ---------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26601
> URL: https://issues.apache.org/jira/browse/CAMEL-26601
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Reporter: shashank
> Assignee: shashank
> Priority: Major
> Fix For: 4.24.0
>
>
> Follow-up of CAMEL-26464 (and CAMEL-26445, CAMEL-26446, CAMEL-26461): the
> same hang for the one case none of them covers, a recipient of a recipient
> list inside a {{doTry}}.
> Found with a SPIN model of the multicast sub task, confirmed with tests on
> the real classes.
> Inside a {{doTry}}, {{MulticastProcessor.wrapInErrorHandler}} does not wrap a
> recipient in an error handler: the recipient gets only the unit of work
> processor. For a multicast the output is a channel, which catches a throw
> since CAMEL-26464; for a recipient list the output is the producer of the
> recipient endpoint. When that producer throws from {{process(exchange,
> callback)}} instead of setting the exception on the exchange, the exception
> reaches the sub task, the reactive executor drops it, and the recipient list
> never completes. The caller waits for good (a {{ProducerTemplate.send}} never
> returns, a consumer thread stays blocked). This happens with the default
> options and with {{synchronous}}, {{parallelProcessing}}, {{stopOnException}}
> and {{shareUnitOfWork}}. With a {{timeout}} the recipient list returns after
> the timeout without the failure, so the {{doCatch}} does not run either.
> Outside a {{doTry}} the error handler around the recipient handles it.
> A producer in Camel itself does this: the seda producer throws
> {{IllegalStateException: Queue full}} from {{process(exchange, callback)}}
> when its bounded queue is full and neither {{blockWhenFull}} nor
> {{discardWhenFull}} is set (the default, documented as "an exception will be
> thrown stating that the queue is full"). Other component producers that throw
> from {{process(exchange, callback)}} hang the same way.
> {code:java}
> from("direct:start")
> .doTry()
> .recipientList(constant("seda:work?size=1"))
> .end()
> .to("mock:result")
> .endDoTry()
> .doCatch(IllegalStateException.class)
> .to("mock:caught")
> .end();
> template.sendBody("seda:work?size=1", "first"); // fills the queue (no
> consumer yet)
> template.sendBody("direct:start", "second"); // never returns; expected:
> mock:caught gets it
> {code}
> *Proposal* (main only, it builds on CAMEL-26464)
> * When the multicast does not wrap the output in an error handler, let its
> unit of work processor catch the throw with the rule of CAMEL-26464
> ({{CamelInternalProcessor}} catchProcessorThrows): the copy is failed with
> the exception, its unit of work is done (a copy with its own unit of work
> leaves the inflight registry, and its completed or failed event fires), and
> the multicast is continued exactly once, so the {{doCatch}} gets it. A catch
> in the sub task itself would fix the hang but skip the unit of work of the
> copy.
> * camel-seda should also set the exception instead of throwing when the queue
> is full (a separate issue); this change is still needed for other producers
> that throw.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)