CAMEL-24284: Reset recoverTask after successful SJMS connection recovery - #25283
CAMEL-24284: Reset recoverTask after successful SJMS connection recovery#25283gansheer wants to merge 1 commit into
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
|
🧪 CI tested the following changed modules:
🔬 Scalpel shadow comparison — Scalpel: 11 tested, 29 compile-only — current: 11 all testedMaveniverse Scalpel detected 40 affected modules (current approach: 11).
|
gnodet
left a comment
There was a problem hiding this comment.
Correct and well-analyzed fix for a real bug where BackgroundTask.schedule() sets running=true but never resets it, causing the re-scheduling guard to permanently block after the first successful recovery. The fix properly uses connectionLock and cancel(false) for thread safety.
Highlights:
- The bug analysis in the PR description is excellent: it accurately identifies that
BackgroundTask.schedule()setsrunning=true(line 144 ofBackgroundTask.java) but only resets it inwaitForTaskCompletion()(line 198), which is only reachable via therun()path, not theschedule()path. The fix of nullingrecoverTaskso the guard passes via therecoverTask==nullpath is the correct caller-side workaround. - Thread safety is properly handled: the fix acquires
connectionLockbefore modifyingrecoverTask/recoverFuture, consistent withscheduleConnectionRecovery()and other methods in this class. The use ofcancel(false)(rather thancancel(true)) is correct since this code runs inside the scheduled task itself —cancel(true)would cause self-interruption.
Minor observations (non-blocking):
- The existing
SjmsConnectionRecoveryTestonly triggersonExceptiononce, so it passes both with and without this fix. A test that triggersonExceptiontwice (with successful recovery between them) would directly cover the bug. Not a blocker given the fix is small and obviously correct. - Pre-existing:
doStop()at line 264 accessesrecoverFutureandrecoverTaskwithout holdingconnectionLock, unlikescheduleConnectionRecovery()and this fix. Mitigated by service lifecycle ordering, but worth noting for future hardening.
Claude Code on behalf of Guillaume Nodet
Description
Fix a bug where the SJMS consumer becomes permanently dead after recovering from a JMS connection failure once — any subsequent connection failure cannot trigger recovery.
Root cause
CAMEL-23646 added a !recoverTask.isRunning() guard in scheduleConnectionRecovery() to allow re-scheduling after a completed task. However, BackgroundTask.schedule() sets running=true but never resets it (running is only cleared in waitForTaskCompletion(), which is the run() path, not the schedule() path).
After the first successful recovery:
Fix
Reset recoverTask and recoverFuture to null (and cancel the scheduled future) after successful recovery. This re-arms the recovery mechanism so subsequent failures can schedule a new recovery task.
Claude Code on behalf of gansheer