[
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)