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

[jira] [Created] (CAMEL-25962) camel-kamelet - removing a Kamelet's route waits for ever while a source Kamelet's threads() pool stays busy, and does not wait for a component's own thread pool

shashank created CAMEL-25962:
--------------------------------

             Summary: camel-kamelet - removing a Kamelet's route waits for ever while a source Kamelet's threads() pool stays busy, and does not wait for a component's own thread pool
                 Key: CAMEL-25962
                 URL: https://issues.apache.org/jira/browse/CAMEL-25962
             Project: Camel
          Issue Type: Improvement
          Components: camel-kamelet
            Reporter: shashank
            Assignee: shashank


With CAMEL-25839 the route of a Kamelet endpoint that is used once and discarded ({{toD}}, {{recipientList}}, {{routingSlip}} with {{cacheSize=-1}}, {{pollEnrich}}) is stopped and removed on a thread of the Kamelet component. The calling route can continue on a thread that the Kamelet's route owns, so the removal waits:

* for the calling exchange to be done, when the endpoint is shut down inside the producer callback ({{toD}});
* for the thread pools that the route's EIPs created ({{threads()}} and the others, tracked with {{LifecycleStrategy.onThreadPoolAdd}} by route id) to be idle, in every case.

Two cases are not covered when the endpoint is shut down where the calling exchange is not known ({{recipientList}}, {{routingSlip}}, {{pollEnrich}} with {{cacheSize=-1}}):

# A thread pool that a component of the route creates for itself, such as the worker pool of an asynchronous {{kafka}} producer (the kafka-sink Kamelet, {{synchronous=false}} by default). The pool is not created by an EIP, so it has no route id. {{KafkaProducer.doStop}} calls {{shutdownGraceful(workerPool, shutdownTimeout)}}: it waits for the calling route to leave the worker thread, up to 30 s by default, while {{stopRoute}} holds the lock of the CamelContext, then interrupts it.
# Executor services that are not a {{ThreadPoolExecutor}} (virtual threads): the removal cannot tell whether a thread is still running, so it does not wait.

h3. Possible fix

For 1: attribute the thread pools created while the Kamelet's route is created and started (on the thread that creates it) to that route, or check the {{ExecutorServiceManager}} for pools whose source is a service of the route. For 2: count the running tasks of the route's virtual-thread executors (a wrapper that counts them). Alternatively, a core hook that gives a prototype endpoint the exchange of the calling route when {{recipientList}}, {{routingSlip}} and {{pollEnrich}} shut it down (for example, shut the prototype endpoint down from an on-completion of the original exchange), which would cover both.

Affected: main, once CAMEL-25839 is merged (before it, the route was never removed).

Also (Claus Ibsen, third review of #28260, reproduced with a probe test on ee985a1c22): the removal task retries every 100 ms with no limit. For the endpoint of a removed route that consumed from a source Kamelet, the first attempt runs at once, so with fast steps the pool is usually idle and the route is removed (timer every 60 s or every 100 ms: removed within about 1 s). When the {{threads()}} pool is busy at that moment (a slow step: HTTP call, database; in the probe {{delay(500).syncDelayed()}} with a timer every 100 ms), every new message then waits up to 30 s on {{kamelet:sink}} ({{block=true}}), the pool never goes idle again, and the Kamelet's route was still there after 45 s in 3 of 3 runs (434 "still has an active thread: removing it later" TRACE lines). Not a regression: before CAMEL-25839 that route was never removed. Proposed fix (Claus): skip the idle wait when the endpoint was the input of a removed route, since no calling route runs on that pool; otherwise stop the route anyway after the shutdown strategy timeout. Test: his {{KameletSourceRemovalProbeTest}} (source template with {{threads(2)}} and a slow step, consumer route removed at runtime, the Kamelet's route must be gone within 30 s).

_Filed with Claude Code on behalf of allthingssecurity._




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)