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

Claus Ibsen updated CAMEL-26579:
--------------------------------
    Fix Version/s: 4.24.0

> camel-core - pooled exchanges: releasing the copy a Split creates (or a part 
> or enrich resource with shareUnitOfWork) resets the parent's unit of work, so 
> its consumer never commits
> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-26579
>                 URL: https://issues.apache.org/jira/browse/CAMEL-26579
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-core
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.24.0
>
>
> With the pooled exchange factory ({{PooledExchangeFactory}} / 
> {{PooledProcessorExchangeFactory}}, deprecated since 4.23 but still 
> supported). Related to CAMEL-24800, which made more pooled copies get reset 
> when released.
> Releasing a pooled copy resets it ({{DefaultPooledExchange.done()}} -> 
> {{resetExtension()}}), and the reset calls {{unitOfWork.reset()}} on the unit 
> of work the copy holds. Some copies hold the unit of work of their *parent* 
> exchange when they are released, so the release resets the parent's unit of 
> work while the parent is still being routed: its synchronizations are cleared 
> and the on completions of the parent (the commit or rollback of its consumer, 
> such as moving or deleting a file, acknowledging a message; route 
> {{onCompletion}}) never run.
> Where a released copy holds the parent's unit of work:
> # *every Split*: the {{Splitter}} copies the exchange once to create the 
> parts from ({{processorExchangeFactory.createCopy}}); a new pooled exchange 
> is created with the copy constructor, which copies the unit of work 
> reference, and the copy is released when the split is done 
> ({{SplitterIterable.close()}});
> # *Split, Multicast and Recipient List with {{shareUnitOfWork}}*: the parts 
> get the parent's unit of work ({{prepareSharedUnitOfWork}}) and are released 
> in {{MulticastProcessor.doDone}};
> # *Enrich with {{shareUnitOfWork}}*: the resource exchange gets the parent's 
> unit of work and is released after the aggregation.
> The released copy also keeps the reference to that unit of work in the pool. 
> And from the second message on, a Split with {{shareUnitOfWork}} takes the 
> copy it creates the parts from out of the pool, where it does not hold the 
> parent's unit of work, but the parts take the unit of work to share from that 
> copy.
> {code:java}
> // with PooledExchangeFactory + PooledProcessorExchangeFactory
> from("direct:start")
>     .process(e -> e.getExchangeExtension().addOnCompletion(commit))   // as a 
> consumer registers its commit
>     .split(body()).to("mock:part").end()
>     .to("mock:result");
> template.sendBody("direct:start", List.of("A", "B"));   // commit.onComplete 
> is never called
> {code}
> The same route without the split, or without the pooled factories, calls it 
> once. For a file consumer this means the file would not be moved or deleted 
> after the route (the commit is such an on completion), so it is picked up 
> again.
> Fix idea: before releasing such a copy, detach the parent's unit of work from 
> it ({{setUnitOfWork(null)}}), at the three release sites (Splitter copy, 
> multicast parts that share it, enrich resource that shares it), and let the 
> parts of a Split share the unit of work of the exchange being split rather 
> than that of the copy. A copy that has its own unit of work is reset as 
> before.
> _Filed with Claude Code on behalf of allthingssecurity._



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

Reply via email to