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

shashank updated CAMEL-25850:
-----------------------------
    Description: 
With {{minThreads}} or {{maxThreads}} set on the Jetty component, 
{{JettyHttpComponent.createServer}} creates a new {{QueuedThreadPool}} for 
every Jetty server (one per host and port), but keeps it in a single component 
field, {{defaultQueuedThreadPool}}, which is overwritten by the next server 
(main 20cdb309f7d0, lines 1335-1375). When the last consumer of a server 
disconnects ({{disconnect}}, lines 546-567, added by CAMEL-14137), the server 
is stopped and then the pool in that field is stopped: that is the pool of the 
last server created, not of the server being stopped. The server does not stop 
its pool itself, as the pool was started before the server.

So with routes on two ports, for example 
{{from("jetty:http://0.0.0.0:8080/a";)}} and 
{{from("jetty:http://0.0.0.0:8081/b";)}} with {{maxThreads=50}} on the 
component, stopping the route on port 8080 (a route stop, a route removal, a 
reload, the route controller) stops the thread pool of the server on port 8081. 
That server then no longer accepts connections (clients get connection refused 
or a timeout) while its route stays Started and nothing is logged. The pool of 
the 8080 server is never stopped: its threads stay for as long as the JVM runs, 
and every stop and start of such a route leaks one more pool.

*Fix*: the pool created for a server is kept with that server in its 
{{ConnectorRef}} and stopped when that server is stopped (in {{disconnect}} and 
in the component's {{doStop}}). The component field is gone; a user-supplied 
{{threadPool}} is still not stopped by Camel. No option changes.

*Tests*: new {{JettyThreadPoolTwoServersTest}} (component with 
{{minThreads=4}}, {{maxThreads=10}}, routes on two ports). 
{{stoppingOneServerKeepsTheOtherServing}}: after stopping route a, route b must 
still answer; on main the request fails with {{java.net.ConnectException}}. 
{{stoppingBothServersStopsBothThreadPools}}: after stopping both routes, no 
thread of the thread pools of the two servers may be left (counted by pool 
name, as the module's test classes run in parallel); on main {{expected: <0> 
but was: <4>}} (the pool that was never stopped). Both pass with the fix. 
camel-jetty unit tests with the fix: 410 run, 23 skipped, 1 error in 
{{JettyXsltHttpTemplateTest}}, which fails the same way on main in this 
environment (it loads a stylesheet over http from 0.0.0.0).

*How it was found*: variant analysis of CAMEL-25846 (a resource that belongs to 
one owner kept where another owner finds and stops it), then the JUnit tests.

*Affected*: main, camel-4.23.x, camel-4.22.x and camel-4.18.x (the same field 
and {{disconnect}}; read, not run).

_Filed with Claude Code on behalf of allthingssecurity._


  was:
With {{minThreads}} or {{maxThreads}} set on the Jetty component, 
{{JettyHttpComponent.createServer}} creates a new {{QueuedThreadPool}} for 
every Jetty server (one per host and port), but keeps it in a single component 
field, {{defaultQueuedThreadPool}}, which is overwritten by the next server 
(main 20cdb309f7d0, lines 1335-1375). When the last consumer of a server 
disconnects ({{disconnect}}, lines 546-567, added by CAMEL-14137), the server 
is stopped and then the pool in that field is stopped: that is the pool of the 
last server created, not of the server being stopped. The server does not stop 
its pool itself, as the pool was started before the server.

So with routes on two ports, for example 
{{from("jetty:http://0.0.0.0:8080/a";)}} and 
{{from("jetty:http://0.0.0.0:8081/b";)}} with {{maxThreads=50}} on the 
component, stopping the route on port 8080 (a route stop, a route removal, a 
reload, the route controller) stops the thread pool of the server on port 8081. 
That server then no longer accepts connections (clients get connection refused 
or a timeout) while its route stays Started and nothing is logged. The pool of 
the 8080 server is never stopped: its threads stay for as long as the JVM runs, 
and every stop and start of such a route leaks one more pool.

*Fix*: the pool created for a server is kept with that server in its 
{{ConnectorRef}} and stopped when that server is stopped (in {{disconnect}} and 
in the component's {{doStop}}). The component field is gone; a user-supplied 
{{threadPool}} is still not stopped by Camel. No option changes.

*Tests*: new {{JettyThreadPoolTwoServersTest}} (component with 
{{minThreads=4}}, {{maxThreads=10}}, routes on two ports). 
{{stoppingOneServerKeepsTheOtherServing}}: after stopping route a, route b must 
still answer; on main the request fails with {{java.net.ConnectException}}. 
{{stoppingBothServersStopsBothThreadPools}}: after stopping both routes, no 
{{CamelJettyServer}} thread may be left; on main {{expected: <0> but was: 
<8>}}. Both pass with the fix. camel-jetty unit tests with the fix: 410 run, 23 
skipped, 1 error in {{JettyXsltHttpTemplateTest}}, which fails the same way on 
main in this environment (it loads a stylesheet over http from 0.0.0.0).

*How it was found*: variant analysis of CAMEL-25846 (a resource that belongs to 
one owner kept where another owner finds and stops it), then the JUnit tests.

*Affected*: main, camel-4.23.x, camel-4.22.x and camel-4.18.x (the same field 
and {{disconnect}}; read, not run).

_Filed with Claude Code on behalf of allthingssecurity._



> camel-jetty - with minThreads or maxThreads, stopping the routes of one port 
> stops the thread pool of the Jetty server of another port, which then accepts 
> no connection
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25850
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25850
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-jetty
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>
> With {{minThreads}} or {{maxThreads}} set on the Jetty component, 
> {{JettyHttpComponent.createServer}} creates a new {{QueuedThreadPool}} for 
> every Jetty server (one per host and port), but keeps it in a single 
> component field, {{defaultQueuedThreadPool}}, which is overwritten by the 
> next server (main 20cdb309f7d0, lines 1335-1375). When the last consumer of a 
> server disconnects ({{disconnect}}, lines 546-567, added by CAMEL-14137), the 
> server is stopped and then the pool in that field is stopped: that is the 
> pool of the last server created, not of the server being stopped. The server 
> does not stop its pool itself, as the pool was started before the server.
> So with routes on two ports, for example 
> {{from("jetty:http://0.0.0.0:8080/a";)}} and 
> {{from("jetty:http://0.0.0.0:8081/b";)}} with {{maxThreads=50}} on the 
> component, stopping the route on port 8080 (a route stop, a route removal, a 
> reload, the route controller) stops the thread pool of the server on port 
> 8081. That server then no longer accepts connections (clients get connection 
> refused or a timeout) while its route stays Started and nothing is logged. 
> The pool of the 8080 server is never stopped: its threads stay for as long as 
> the JVM runs, and every stop and start of such a route leaks one more pool.
> *Fix*: the pool created for a server is kept with that server in its 
> {{ConnectorRef}} and stopped when that server is stopped (in {{disconnect}} 
> and in the component's {{doStop}}). The component field is gone; a 
> user-supplied {{threadPool}} is still not stopped by Camel. No option changes.
> *Tests*: new {{JettyThreadPoolTwoServersTest}} (component with 
> {{minThreads=4}}, {{maxThreads=10}}, routes on two ports). 
> {{stoppingOneServerKeepsTheOtherServing}}: after stopping route a, route b 
> must still answer; on main the request fails with 
> {{java.net.ConnectException}}. {{stoppingBothServersStopsBothThreadPools}}: 
> after stopping both routes, no thread of the thread pools of the two servers 
> may be left (counted by pool name, as the module's test classes run in 
> parallel); on main {{expected: <0> but was: <4>}} (the pool that was never 
> stopped). Both pass with the fix. camel-jetty unit tests with the fix: 410 
> run, 23 skipped, 1 error in {{JettyXsltHttpTemplateTest}}, which fails the 
> same way on main in this environment (it loads a stylesheet over http from 
> 0.0.0.0).
> *How it was found*: variant analysis of CAMEL-25846 (a resource that belongs 
> to one owner kept where another owner finds and stops it), then the JUnit 
> tests.
> *Affected*: main, camel-4.23.x, camel-4.22.x and camel-4.18.x (the same field 
> and {{disconnect}}; read, not run).
> _Filed with Claude Code on behalf of allthingssecurity._



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

Reply via email to