[ 
https://issues.apache.org/jira/browse/CAMEL-26663?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18139147#comment-18139147
 ] 

Claus Ibsen commented on CAMEL-26663:
-------------------------------------

PR: https://github.com/apache/camel/pull/29278

The exchange is now put into the recovery map before it is removed from the 
active map. When the optimistic remove fails, it is taken out of the recovery 
map again.

_Claude Code on behalf of davsclaus_

> camel-hazelcast - HazelcastAggregationRepository optimistic remove() can lose 
> a completed group
> -----------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-26663
>                 URL: https://issues.apache.org/jira/browse/CAMEL-26663
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-hazelcast
>            Reporter: Claus Ibsen
>            Assignee: Claus Ibsen
>            Priority: Minor
>
> This has the same flaw as CAMEL-26395 (camel-redis).
> In {{HazelcastAggregationRepository.remove()}} with {{optimistic=true}} and 
> {{useRecovery=true}}, the group is removed from the active map first 
> ({{cache.remove(key, holder)}}). Only afterwards is it written to the 
> recovery map ({{persistedCache.put(exchangeId, holder)}}). If the JVM crashes 
> between the two calls, or the {{put}} throws, the completed group is in 
> neither map and is lost.
> The pessimistic branch does not have this problem, because it runs both steps 
> in a Hazelcast transaction.
> Suggested fix, the same as the one proposed on CAMEL-26395:
> # When {{useRecovery}} is true, put the exchange in the recovery map first.
> # Then call {{cache.remove(key, holder)}}.
> # If the remove fails, remove the staged entry from the recovery map and 
> throw {{OptimisticLockingException}}. If that cleanup fails too, log a WARN 
> with the cause and still throw {{OptimisticLockingException}}.
> In the worst case a group is then sent twice instead of being lost. On the 
> same node, the recover task cannot pick up the staged entry early: 
> {{AggregateProcessor}} marks the exchange as completing before it calls 
> {{remove()}}, and the recover task skips those exchanges. Another Camel node 
> does not see that mark, so it could briefly recover a staged entry whose 
> remove then fails. The PR should mention this.
> Tests to add:
> * The recovery {{put}} fails: {{remove()}} throws, and the group is still in 
> the active map.
> * A remove with a stale holder throws {{OptimisticLockingException}} and 
> leaves nothing in the recovery map.
> _Claude Code on behalf of davsclaus_



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

Reply via email to