CAMEL-24242: camel-aws2-athena - stop ignoring thread interruption while polling a query#25029
CAMEL-24242: camel-aws2-athena - stop ignoring thread interruption while polling a query#25029oscerd wants to merge 1 commit into
Conversation
…ile polling a query Athena2QueryHelper.interrupted gates both shouldAttempt() and shouldWait(), but nothing assigned it any more, so both guards were dead code. CAMEL-20297 had added interrupt handling in doWait(); the CAMEL-22949 migration to Camel's Task API (commit 1b0fca1) replaced the Thread.sleep() block along with the catch clause that was its only writer, silently reverting it. ForegroundTask.run() does restore the interrupt status and return false, but doWait() discarded that result. The consequence was worse than a missed shutdown signal: once the interrupt status is set, every subsequent Thread.sleep() inside the task returns immediately, so the polling loop spun with no delay, issuing GetQueryExecution calls as fast as the API allowed until waitTimeout elapsed. Capture the return value and record the interruption, restoring CAMEL-20297's behaviour on top of the Task API. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Andrea Cosentino <ancosen@gmail.com>
gnodet
left a comment
There was a problem hiding this comment.
Clean, well-documented fix for the interrupt-handling regression introduced by the Task API migration (CAMEL-22949). The analysis tracing the issue through CAMEL-20297 → CAMEL-22949 is excellent, and the test correctly validates all three observable effects.
One minor note: adding assertj-core as a new test dependency for 4 boolean assertions could be replaced by JUnit's built-in assertTrue/assertFalse (the rest of the test file already uses them). Not blocking since assertj is managed in the parent POM and widely used elsewhere.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of @gnodet
|
🌟 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: 9 tested, 29 compile-only — current: 9 all testedMaveniverse Scalpel detected 38 affected modules (current approach: 9).
|
davsclaus
left a comment
There was a problem hiding this comment.
Clean bug fix — the regression analysis is thorough and the fix is correctly targeted.
Verified that ForegroundTask.run() catches InterruptedException, restores the interrupt status, and returns false — so the new !completed && Thread.currentThread().isInterrupted() guard correctly bridges the Task API's interrupt signaling back to the Athena2QueryHelper.interrupted field that gates both polling loops.
The test properly sets the interrupt flag before calling doWait(), asserts all three loop-exit conditions (isInterrupted(), shouldWait(), shouldAttempt()), and clears the flag in a finally block to prevent leakage.
This review was generated by an AI agent (Claude Code on behalf of davsclaus) and may contain inaccuracies. Please verify all suggestions before applying.
Problem
Athena2QueryHelper.interruptedgates both loops that drivestartQueryExecution:It is read at
Athena2QueryHelper.java:113(shouldAttempt) and:146(
shouldWait) — and never assigned anywhere in the class. Both guards aredead code.
How it regressed
This is a silent revert of a deliberate fix, so I want to be explicit about the
history:
CAMEL-20297 (
9e17300779, Otavio Piske, Jan 2024) — "camel-aws2-athena:do not swallow interrupted exceptions" — added the interrupt handling:
CAMEL-22949 (
1b0fca17c0, PR CAMEL-22949: Migrate components from Thread.sleep() to Camel's Task API #21215, Feb 2026) — "Migrate components fromThread.sleep() to Camel's Task API" — replaced that block with
Tasks.foregroundTask()...run(...)and dropped thecatchclause, which wasthe only writer of
interrupted.Impact
ForegroundTask.run()does restore the interrupt status(
ForegroundTask.java:124) and returnfalse— butdoWait()discarded thereturn value. The result is worse than a missed shutdown signal. After the first
interruption:
shouldWait()still returnstrue, becauseinterruptedisfalse;doWait()reachesThread.sleep(initialDelay)insideForegroundTask.run(), which throwsInterruptedExceptionimmediatelybecause the status is set, and returns at once;
GetQueryExecutioncalls as fast as the API allows untilwaitTimeoutelapses — and up to
maxAttempts × waitTimeoutwhenresetWaitTimeoutOnRetry=true.So interrupting an in-flight query (graceful shutdown, route stop) turns a
2-second-interval poll into a tight busy loop against the Athena API.
Fix
Capture the
run()return value and record the interruption:The interrupt status itself is left in place —
ForegroundTaskalready restoredit, which is what CAMEL-20297 wanted the caller to observe.
Test
Athena2QueryHelperTest.doWaitRecordsThreadInterruptionSoTheLoopsStop()interruptsthe calling thread, calls
doWait(), and asserts thatisInterrupted(),shouldWait()andshouldAttempt()all report the query loop should stop. Itclears the interrupt status in a
finallyblock so it cannot leak intoneighbouring tests.
Verified it fails on
main(Expecting value to be true but was false) andpasses with the fix. Full class: 23/23 green.
assertj-coreis added test-scoped for the new assertions; the pre-existingJUnit assertions in the file are left untouched.
Backport
camel-4.18.x— affected (carries the CAMEL-22949 migration) → backport opened.camel-4.14.x— not affected; it still has the originalThread.sleep()with the
catch (InterruptedException)block, so there is nothing to fix there.Claude Code on behalf of oscerd