[
https://issues.apache.org/jira/browse/CAMEL-26663?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-26663:
--------------------------------
Fix Version/s: 4.24.0
> 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
> Fix For: 4.24.0
>
>
> 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)