CAMEL-24243: camel-aws2-athena - do not relaunch a still-running query when waitTimeout expires#25040
CAMEL-24243: camel-aws2-athena - do not relaunch a still-running query when waitTimeout expires#25040oscerd wants to merge 1 commit into
Conversation
…y when waitTimeout expires The inner wait loop in Athena2Producer.startQueryExecution exits on three conditions: success, failure/retry, and waitTimeout expiry. Only the first two set state on the helper, because setStatusFrom() assigns isSuccess/isFailure/ isRetry only for a completed query. So when the wait window elapsed while the query was still QUEUED or RUNNING, shouldAttempt() saw no completion state and returned true, and the outer loop submitted a brand-new Athena query. With maxAttempts > 1 that abandons the running execution -- still scanning, still billed -- and returns the queryExecutionId of the last submission, so the caller cannot correlate or cancel the earlier ones. clientRequestToken is not auto-generated, so Athena does not deduplicate them either. The documented contract is that attempts are consumed by retrying *failed* queries, not by queries that are merely slow. Treat waitTimeout expiry as terminal for the attempt loop, and keep consuming an attempt for a completed-and-retryable failure. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Andrea Cosentino <ancosen@gmail.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: 9 tested, 29 compile-only — current: 9 all testedMaveniverse Scalpel detected 38 affected modules (current approach: 9).
|
gnodet
left a comment
There was a problem hiding this comment.
Correct fix for a real bug where a still-running Athena query was relaunched when waitTimeout expired, orphaning the previous execution. The isWaitTimeoutExceeded() guard in shouldAttempt() correctly closes the gap, and its interaction with isRetry ensures retryable failures still get another attempt.
The regression test aStillRunningQueryIsNotRelaunchedWhenTheWaitTimeoutExpires directly reproduces the bug scenario, and the retry-path test guards against over-suppression. CI passes on both JDK 17 and 25.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of Guillaume Nodet
Problem
Athena2Producer.startQueryExecution()drives two nested loops:The inner loop exits on three conditions: success, failure/retry, and
waitTimeoutexpiry. Only the first two set state on the helper —setStatusFrom()assignsisSuccess/isFailure/isRetryonly when the queryhas actually completed.
When the inner loop exits because
millisWaited >= waitTimeoutwhile the queryis still
QUEUED/RUNNING, none of those flags are set.shouldAttempt()thensees
attempts < maxAttempts, no failure, no success, not interrupted — andreturns
true. The outer loop callsdoStartQueryExecutionagain, submittinga brand-new Athena query while the previous one is still running.
Impact
With
maxAttempts > 1(the documented way to retry failed queries):waitTimeoutexpiry submits another execution of the same SQL;CamelAwsAthenaQueryExecutionIdheader returned to the route belongs tothe last submission, so the caller cannot correlate or cancel the earlier ones;
clientRequestTokenis not auto-generated(
Athena2Producer.determineClientRequestTokenreads only a header or theendpoint option), so Athena does not deduplicate the submissions by default.
This contradicts the documented contract in
aws2-athena-component.adoc:Retry is documented as a response to failure states, not to a query simply
taking longer than
waitTimeout.Fix
Treat
waitTimeoutexpiry as terminal for the attempt loop.shouldAttempt()now bails out when the wait window elapsed while the query was still running,
after success and failure have been ruled out:
A completed-and-retryable failure still consumes another attempt, because
setStatusFrom()setsisRetryfor it beforeshouldAttempt()runs — so thedocumented retry behaviour is preserved.
Tests
aStillRunningQueryIsNotRelaunchedWhenTheWaitTimeoutExpires()— query staysRUNNINGpast the wait window; assertsshouldAttempt()isfalseandattemptsstays at 1. Fails onmain(Expecting value to be false but was true), passes with the fix.aRetryableFailureStillConsumesAnotherAttemptAfterTheWaitTimeout()— aGENERIC_INTERNAL_ERRORwithretry=alwaysstill yieldsshouldAttempt() == true, guarding the retry path.Full class 24/24 green.
assertj-coreadded test-scoped for the new assertions.Backport
The loop is identical on
main,camel-4.18.xandcamel-4.14.x→ targeted at4.22.0, 4.18.4, 4.14.9.
Claude Code on behalf of oscerd