ai-yang opened a new issue, #10739:
URL: https://github.com/apache/rocketmq/issues/10739

   ## RocketMQ version
   
   `develop` at `00e45b8a6db23efbe756d0306f10716156cfd4dd`
   
   ## Describe the bug
   
   `FutureUtils.appendNextFuture` ignores the dependent stage returned by
   `whenCompleteAsync`. If the supplied executor rejects the completion task, 
that
   dependent stage completes exceptionally but the manually created `nextFuture`
   is never completed.
   
   The production executors used by `ProducerProcessor` and `ConsumerProcessor`
   add a second failure mode. They are created through the default
   `ThreadPoolMonitor.createAndMonitor` overload, whose rejection handler is
   `DiscardOldestPolicy`. After shutdown it silently discards the completion 
task;
   under saturation it can silently discard an older queued completion task.
   Neither case gives `FutureUtils` a rejection that it can propagate, so a 
proxy
   request future can remain pending indefinitely.
   
   ## Deterministic reproduction
   
   Two synchronous regression tests reproduce the complete failure chain on JDK 
8.
   
   ### 1. Rejection is not propagated by `FutureUtils`
   
   1. Create a single-thread executor and shut it down.
   2. Call `FutureUtils.addExecutor(CompletableFuture.completedFuture("value"), 
executor)`.
   3. Inspect the returned future.
   
   Expected: the returned future is completed exceptionally with the scheduling
   failure.
   
   Actual: the stage returned by `whenCompleteAsync` is exceptional, but the 
stage
   is ignored and the returned `nextFuture` remains pending.
   
   The controlled test
   
`FutureUtilsTest#testAddExecutorCompletesExceptionallyWhenExecutorRejectsTask`
   failed at the expected `result.isDone()` assertion in 5/5 runs.
   
   ### 2. The actual Proxy processor executor silently drops the task
   
   1. Construct `DefaultMessagingProcessor` with its real producer and consumer
      processor executors.
   2. Shut down the producer processor executor.
   3. Pass that executor to `FutureUtils.addExecutor` with an already completed
      source future.
   4. Inspect the returned future.
   
   Expected: rejection is observable and the returned future is completed
   exceptionally.
   
   Actual: `DiscardOldestPolicy` silently discards the task after shutdown and 
the
   returned future remains pending.
   
   The controlled test
   
`DefaultMessagingProcessorTest#testProcessorFutureCompletesWhenExecutorIsShutDown`
   failed at the expected `result.isDone()` assertion in 5/5 runs. It uses the
   actual processor pool, no sleeps, randomized scheduling, network access, or
   external service.
   
   ## Impact
   
   `FutureUtils.addExecutor` is used by the Proxy `ProducerProcessor` and
   `ConsumerProcessor` request paths. During processor-pool shutdown, or when 
the
   bounded pool rejects completion work, callers may receive a future that never
   reaches a terminal state. This can leave gRPC/remoting requests waiting 
until an
   outer timeout or connection teardown instead of receiving an immediate 
failure.
   
   ## Suggested fix
   
   Both parts are needed; either one alone leaves a pending-future path:
   
   - Retain the stage returned by `whenCompleteAsync` and propagate a scheduling
     failure into `nextFuture`.
   - Create the producer and consumer processor executors with an explicit
     throwing rejection policy (for example `AbortPolicy`) instead of the 
default
     silent `DiscardOldestPolicy`, so `FutureUtils` can observe both shutdown 
and
     overload rejection.
   - Add regression coverage for both a throwing executor and the actual Proxy
     processor executor after shutdown.
   
   This changes only internal completion/rejection behavior and does not change 
a
   public protocol.
   
   ## Related work checked
   
   - #8900 contains a `FutureUtils` stack frame but reports client cancellation 
and
     message redelivery, not executor rejection or a pending returned future.
   - #9253 concerns receipt-handle renewal after client disconnection, not
     completion-task rejection.
   - #5575 introduced the Proxy remoting implementation and is not a fix for 
this
     behavior.
   - #10711 concerns unsupported metadata futures and does not modify
     `FutureUtils` or the processor executor policies.
   
   Searches across open and closed issues and pull requests for `FutureUtils`,
   `addExecutor`, `DefaultMessagingProcessor`, `DiscardOldestPolicy`, executor
   shutdown/rejection, and pending Proxy futures found no equivalent report or
   claimed fix.
   


-- 
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]

Reply via email to