You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Andrea Cosentino (Jira)" <ji...@apache.org> on 2026/07/22 11:26:00 UTC

[jira] [Created] (CAMEL-24242) camel-aws2-athena: thread interruption during query polling is ignored, causing a busy poll loop

Andrea Cosentino created CAMEL-24242:
----------------------------------------

             Summary: 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


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)