[ 
https://issues.apache.org/jira/browse/CAMEL-25037?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen resolved CAMEL-25037.
---------------------------------
    Resolution: Fixed

Fixed by https://github.com/apache/camel/pull/26912 (merged as 17f4f62c7eb3).

_Claude Code on behalf of davsclaus_

> camel-support - an interrupted EventDrivenPollingConsumer.receive() never 
> returns: it loops at 100 % CPU and logs a WARN on every iteration (regression 
> of CAMEL-20297, 4.4)
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25037
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25037
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-core
>            Reporter: shashank
>            Priority: Minor
>             Fix For: 4.23.0
>
>
> {{EventDrivenPollingConsumer.receive()}} 
> ({{core/camel-support/.../EventDrivenPollingConsumer.java:128-153}}) loops 
> {{while (isRunAllowed())}} around {{queue.take()}}. On 
> {{InterruptedException}} it calls {{handleInterruptedException}} 
> ({{:236-239}}). Since CAMEL-20297 (commit ff48bbc4d2, 4.4.0) that method 
> restores the interrupt flag ({{Thread.currentThread().interrupt()}}) and then 
> logs through the {{LoggingExceptionHandler}} at WARN. The loop then calls 
> {{take()}} again, which throws at once because the flag is set, and so on. 
> The thread never leaves {{receive()}}, even when a message is queued, because 
> {{take()}} checks the flag first. It uses a full core and writes one WARN 
> line per iteration.
> This is the same pattern as CAMEL-22390 (SedaConsumer infinite loop on 
> interrupt, also caused by CAMEL-20297). That issue was closed as "Information 
> Provided" with the advice that end users should not interrupt Camel's own 
> threads. The case here is different. {{ConsumerTemplate.receive()}} and 
> {{PollingConsumer.receive()}} run on the caller's own thread, which the 
> application may legitimately interrupt or cancel. Camel itself also 
> interrupts route threads during a forced shutdown. A blocking {{receive()}} 
> that is interrupted should return, not spin.
> A thread in {{receive()}} gets interrupted when, for example:
> * a task doing {{consumerTemplate.receive(uri)}} is cancelled with 
> {{Future.cancel(true)}}, or its executor is shut down with {{shutdownNow()}};
> * the thread pool of a route that waits in {{pollEnrich}} (default timeout 
> -1) is shut down with {{shutdownNow()}}, which Camel does on a forced 
> shutdown (for example the Threads EIP pool in 
> {{ThreadsProcessor.doShutdown}}, or {{BaseExecutorServiceManager.doShutdown}} 
> after its await timeout).
> Affected: 4.4.0 and later (4.4.x, 4.8.x, 4.14.x, 4.18.x, main).
> *Reproduction* (4.23.0-SNAPSHOT):
> {noformat}
> thread A: consumerTemplate.receive("direct:idle")   -> waiting in 
> EventDrivenPollingConsumer.receive:141
> A.interrupt()
> 2 s later: A alive=true state=RUNNABLE, CPU time used by A in those 2 s = 
> 1979 ms
> 200 stack samples of A: EventDrivenPollingConsumer.receive:141 / 
> handleInterruptedException:237 / LoggingExceptionHandler
> with log4j at WARN: 603,114 lines "WARN EventDrivenPollingConsumer - Caused 
> by: [java.lang.InterruptedException - null]"
>                     in about 3 s (the log file reached 544 MB)
> {noformat}
> With the fix below {{receive()}} returns null 591 ms after the interrupt and 
> the thread ends.
> TLA+: the same model with interrupts violates {{ReceiveEndsAfterInterrupt}} 
> ({{pc_shared_interrupt_live}}). The lasso is Interrupt -> RIntr -> RLoop -> 
> RAcq -> RIntr ..., and it holds even with a message in the queue. The fix 
> variant ({{pc_fix_interrupt}}) satisfies it.
> *Proposed fix:* on {{InterruptedException}} in {{receive()}} / 
> {{receive(timeout)}}, restore the interrupt flag and return null (leave the 
> loop). Do not call {{take()}} again. Optionally log once at DEBUG, like 
> {{process()}} does for an interrupted put.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to