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

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

Fixed by https://github.com/apache/camel/pull/28537

> camel-thrift - the asynchronous producer (the default) never stops its 
> TAsyncClientManager: a selector thread and a selector leak per producer start
> ----------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-26050
>                 URL: https://issues.apache.org/jira/browse/CAMEL-26050
>             Project: Camel
>          Issue Type: Bug
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.24.0
>
>
> The thrift producer is asynchronous by default ({{synchronous=false}}). 
> {{ThriftProducer.doStart}} builds its client with 
> {{ThriftUtils.constructAsyncClientInstance}}, which creates a {{new 
> TAsyncClientManager()}} each time (a {{TAsyncClientManager#SelectorThread}} 
> and an NIO selector). {{doStop}} only closes the transport, and nothing calls 
> {{TAsyncClientManager.stop()}} (main 0c1e85c8631c). A route restart creates a 
> new producer, so each restart (and each producer evicted from a {{toD}} or 
> ProducerTemplate cache) leaks a selector thread and a selector until the JVM 
> exits. The module has no test of the asynchronous producer (all producer 
> tests use {{synchronous=true}}).
> *Fix*: {{ThriftProducer}} creates the manager, passes it to a new 
> {{ThriftUtils.constructAsyncClientInstance(..., TAsyncClientManager)}} 
> overload and stops it in {{doStop}} (libthrift 0.25.0: {{stop()}} ends the 
> selector thread, which closes the selector). The existing 5-argument method 
> is kept (it now creates its manager and delegates to the overload; an 
> {{IOException}} of {{new TAsyncClientManager()}} now gives the message 
> {{Thrift async client manager cannot be created}}). An asynchronous call sent 
> just before the producer stops never gets its callback, so its exchange does 
> not complete: after {{stop()}} the selector thread only closes the selector 
> (javap {{SelectThread.run}}), so a call not started yet or registered on the 
> selector gets neither {{onComplete}} nor {{onError}} (on main a call not 
> started yet got {{ClosedChannelException}} through {{onError}}, one already 
> registered hung too). A graceful shutdown drains inflight exchanges first, so 
> only cache eviction or a shutdown timeout can hit this.
> *Tests*: new {{ThriftProducerAsyncStopTest}}: 5 restarts of a route with an 
> asynchronous ping producer (a ping after each), then a stop; 
> {{routeRestartsStopTheClientManagersOfTheStoppedProducers}} fails on main: 
> {{selector threads of stopped asynchronous producers ==> expected: <0> but 
> was: <5>}}. Unit tests of camel-thrift with the fix: 56 run, 0 failures.
> *How it was found*: a per-class thread/fd leak check over module test suites 
> and a route restart probe (r75).
> *Affected*: main, camel-4.23.x, camel-4.22.x, camel-4.18.x and camel-4.14.x 
> (same code). Read, not run.
> _Filed with Claude Code on behalf of allthingssecurity._



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

Reply via email to