jamespud opened a new pull request, #16418:
URL: https://github.com/apache/dubbo/pull/16418

   ## What is the purpose of the change
   
   Fixes #16415.
   
   When a sync Triple call times out, `AsyncRpcResult#get(timeout)` shuts down 
the per-call `ThreadlessExecutor` in a `finally` block. Any DATA frame that 
arrives afterwards is handed to 
`AbstractTripleClientStream.ClientTransportListener.onData()`, which submits 
the decode task via `SerializingExecutor`. Because the underlying executor is 
already shut down, `SerializingExecutor` silently removes the task from its 
queue and returns without throwing (a behavior introduced in #15122). As a 
result `doOnData()` never runs and the DATA frame's `ByteBuf` (wrapped in 
`ByteBufInputStream(data, true)` only inside `doOnData`) is never released — a 
Netty ByteBuf leak that grows on every timed-out call with in-flight response 
data.
   
   ## Root cause
   
   `SerializingExecutor.schedule()` swallows the rejection when the underlying 
executor is shut down. `ThreadlessExecutor.execute()` already throws 
`RejectedExecutionException` in that case, but `SerializingExecutor` catches it 
and (when shut down) silently drops the user-submitted task, so the caller 
never learns the task was rejected and cannot release task-owned resources.
   
   ## Brief changelog
   
   1. `SerializingExecutor` (`dubbo-common`): when a user-submitted task cannot 
be scheduled because the underlying executor is shut down, propagate 
`RejectedExecutionException` instead of silently dropping it. The internal 
reschedule from `run()` keeps the original ignore-if-shutdown behavior.
   2. `AbstractServerTransportListener` (`dubbo-rpc-triple`): guard 
`onData`/`onMetadata` so an inbound message is closed via `onDataFinally` when 
the executor rejects the task.
   3. `AbstractTripleClientStream` (`dubbo-rpc-triple`): the existing catch in 
`onData` now releases the ByteBuf when the executor rejects the task; log level 
adjusted to WARN since dropping late data after a timeout is expected.
   
   ## Verifying the change
   
   - 
`SerializingExecutorTest#testRejectedExecutionWhenUnderlyingExecutorShutdown` 
(new): submitting to a `SerializingExecutor` whose underlying executor is shut 
down throws `RejectedExecutionException` and the task does not run.
   - 
`TripleClientStreamTest#testOnDataReleaseByteBufAfterCallbackExecutorShutdown` 
(new): a DATA-frame ByteBuf received after the callback executor is shut down 
is released (`refCnt == 0`). This test fails before the fix (`refCnt == 1`).
   
   Fixes #16415


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to