davsclaus opened a new pull request, #29278:
URL: https://github.com/apache/camel/pull/29278

   _Claude Code on behalf of davsclaus_
   
   ## What
   
   [CAMEL-26663](https://issues.apache.org/jira/browse/CAMEL-26663): with 
`optimistic=true` and recovery on, `HazelcastAggregationRepository.remove()` 
removed the group from the active map **before** it put the exchange into the 
recovery map. A crash between the two calls, or a failed `put`, lost the 
completed group. This is the same flaw as CAMEL-26395 in camel-redis.
   
   ## Fix
   
   - When recovery is on, put the exchange into the recovery map first, then 
call `cache.remove(key, holder)`.
   - If the optimistic remove fails, remove the exchange from the recovery map 
again and throw `OptimisticLockingException` as before. If that cleanup fails 
too, log a WARN with the cause and still throw `OptimisticLockingException`.
   - The pessimistic (transactional) branch is unchanged.
   
   In the worst case a group is now sent twice instead of being lost.
   
   On the same node, the recover task cannot pick up the 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. If this node's remove then fails, another node could recover 
the entry in the short window before the cleanup removes it.
   
   If `cache.remove` throws (instead of returning false) after the put, the 
recovery entry stays. The remove may have happened on the cluster even though 
the call failed, so deleting the entry could lose the group.
   
   ## Tests
   
   New tests in `HazelcastAggregationRepositoryOperationsTest`:
   - `checkOptimisticRemoveKeepsTheGroupWhenTheRecoverableStorageFails`: the 
recovery `put` fails; `remove()` throws and the group is still in the active 
map. **This test fails on main.**
   - `checkOptimisticRemoveOfAStaleExchangeLeavesNothingToRecover`: a remove 
with a stale exchange throws `OptimisticLockingException` and leaves nothing in 
the recovery map.
   - `checkOptimisticRemoveOfAStaleExchangeFailsWhenTheCleanupFails`: the 
cleanup fails; `OptimisticLockingException` is still thrown.
   
   All 276 camel-hazelcast tests and `HazelcastRoutePolicyIT` pass locally.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to