shashank created CAMEL-26050:
--------------------------------
Summary: 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
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)