[
https://issues.apache.org/jira/browse/CAMEL-24242?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Andrea Cosentino reassigned CAMEL-24242:
----------------------------------------
Fix Version/s: 4.22.0
4.18.4
Assignee: Andrea Cosentino
> camel-aws2-athena: thread interruption during query polling is ignored,
> causing a busy poll loop
> ------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24242
> URL: https://issues.apache.org/jira/browse/CAMEL-24242
> Project: Camel
> Issue Type: Bug
> Components: camel-aws
> Reporter: Andrea Cosentino
> Assignee: Andrea Cosentino
> Priority: Major
> Fix For: 4.18.4, 4.22.0
>
>
> h3. Problem
> {{Athena2QueryHelper}} has an {{interrupted}} flag that gates both
> {{shouldAttempt()}} and {{shouldWait()}}:
> {code:java}
> if (this.interrupted) {
> LOG.trace("AWS Athena start query execution thread was interrupted, will
> try no more");
> return false;
> }
> {code}
> The flag is *never assigned* anywhere in the class. It is read at
> {{Athena2QueryHelper}} lines 113 and 146 (and by the getter at line 459) but
> has no writer, so it is permanently {{false}} and both guards are dead code.
> h3. How it regressed
> CAMEL-20297 ("camel-aws2-athena: do not swallow interrupted exceptions",
> commit 9e17300779) deliberately added interrupt handling in {{doWait()}}:
> {code:java}
> try {
> Thread.sleep(this.currentDelay);
> } catch (InterruptedException e) {
> this.interrupted = Thread.interrupted(); // store, then clear, interrupt
> status
> LOG.trace("...wait thread was interrupted; will return at earliest
> opportunity");
> Thread.currentThread().interrupt();
> }
> {code}
> CAMEL-22949 ("Migrate components from Thread.sleep() to Camel's Task API",
> commit 1b0fca17c0, PR #21215) replaced that block with
> {{Tasks.foregroundTask()...run(...)}} and dropped the {{catch}} clause --
> which was the only writer of {{interrupted}}. The migration silently reverted
> CAMEL-20297.
> h3. Impact
> {{ForegroundTask.run()}} does restore the interrupt flag (ForegroundTask line
> 124) and returns {{false}}, but {{doWait()}} discards the return value. So
> after the first interruption:
> # the thread's interrupt flag stays set;
> # {{shouldWait()}} still returns true because {{interrupted}} is false;
> # the next {{doWait()}} hits {{Thread.sleep(initialDelay)}} inside
> {{ForegroundTask.run()}}, which throws {{InterruptedException}} *immediately*
> because the flag is set, and returns at once;
> # the polling loop therefore spins with *no delay*, issuing
> {{GetQueryExecution}} calls as fast as the API allows, until {{waitTimeout}}
> elapses.
> So an interrupt (for example during graceful shutdown or route stop) turns a
> well-behaved 2-second-interval poll into a tight busy loop against the AWS
> Athena API, for up to {{waitTimeout}} -- and up to {{maxAttempts x
> waitTimeout}} when {{resetWaitTimeoutOnRetry=true}}.
> h3. Proposed fix
> Capture the {{run()}} return value in {{doWait()}} and set {{interrupted}}
> when the task did not complete and the thread's interrupt status is set,
> restoring the CAMEL-20297 behaviour on top of the Task API.
> h3. Affected versions
> * {{main}} / 4.22.0 -- affected
> * {{camel-4.18.x}} -- affected (carries the CAMEL-22949 migration)
> * {{camel-4.14.x}} -- *not* affected, still has the original {{Thread.sleep}}
> + interrupt handling
> ----
> _Reported by Claude Code on behalf of acosentino, from an automated audit of
> the camel-aws components._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)