[ 
https://issues.apache.org/jira/browse/CAMEL-26459?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Work on CAMEL-26459 started by shashank.
----------------------------------------
> camel-disruptor - multipleConsumers: when a consumer fails, a consumer that 
> gets to the message later routes an already failed copy and never processes it
> ----------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-26459
>                 URL: https://issues.apache.org/jira/browse/CAMEL-26459
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-disruptor
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>
> Found in the review of CAMEL-26458 (camel-disruptor, {{multipleConsumers}}: 
> on completions run twice).
> With {{multipleConsumers=true}} each consumer routes its own copy of the 
> published exchange: {{DisruptorConsumer.prepareExchange}} copies the 
> published exchange when that consumer gets to the event. When a consumer 
> fails, {{MultipleConsumerSynchronizedExchange.consumed}} completes the 
> exchange right away (early completion) and copies the failure into the shared 
> published exchange first ({{ExchangeHelper.copyResults(getExchange(), 
> result)}}). A consumer that has not started on that event yet (its thread is 
> still busy with an earlier event) then copies an exchange that already has 
> the exception, so its route stops after the first step: that consumer never 
> processes the message, and nothing is logged as a failure of that consumer.
> {code:java}
> from("disruptor:fan?multipleConsumers=true")      // consumer 1: fails m2 at 
> once
>     .filter(body().isEqualTo("m2")).throwException(new 
> IllegalArgumentException("Forced"));
> from("disruptor:fan?multipleConsumers=true")      // consumer 2: busy with m1 
> for a while
>     .process(e -> { /* slow for m1 */ })
>     .to("mock:c2");                               // never gets m2
> {code}
> Reproduced with latches (no sleeps): consumer 2 waits on a latch while 
> routing m1; consumer 1 fails m2 and the caller's on completion reports the 
> failure of m2; then consumer 2 is released: it routes m1 and never m2 (its 
> copy of m2 already has the exception, so its route stops before {{mock:c2}}). 
> A SPIN model of the two consumers (the published exchange written by the 
> early completion, copied later by the other consumer) shows the same order, 
> and that running the early completion on a copy of the published exchange 
> keeps the copies clean.
> The early completion also runs the on completions of the caller's exchange 
> (such as the rollback of a file consumer: read lock and in-progress mark 
> released) while the other consumers are still routing the message, so the 
> source may hand the same message out again meanwhile. camel-seda completes 
> the exchange of {{multipleConsumers}} once, after all consumers are done.
> With a waiting producer (InOut) the producer has already been answered by 
> then, so a late consumer skips the message (the copy is marked to be ignored) 
> instead of routing a failed copy.
> Same on main before and after CAMEL-26458.
> *Proposal* (to discuss): either complete the exchange once when all consumers 
> are done (as seda; a waiting producer then gets the failure when all 
> consumers are done, bounded by its timeout), or keep the early completion but 
> run it on a copy of the published exchange, so that the published exchange is 
> not written after it was published and later consumers copy the message as it 
> was sent. Tests: a consumer that is busy with an earlier message when another 
> consumer fails the next one still routes it.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to