apache / apache/rocketmq

[Bug] InvocationChannel cleanup drops expired local proxy futures

Open
#10,764 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
22.6k
Forks
12k
Avg merge
3d 1h
Merged PRs (30d)
27

Description

### Before Creating the Bug Report

- [x] I have confirmed this problem is not already covered by an existing issue or open pull request.

### Runtime platform environment

Any RocketMQ Proxy local-mode deployment that uses `InvocationChannel` for local remoting requests.

### RocketMQ version

develop branch

### JDK Version

N/A

### Describe the Bug

`InvocationChannel.clearExpireContext()` removes expired local invocation contexts without completing the response future held by `InvocationContext`.

Local-mode `sendMessage()` and `popMessage()` create a `CompletableFuture`, wrap it in `InvocationContext`, and register it against the request opaque. If the response is never written back and the periodic channel cleanup expires the context, the map entry is removed, but the waiting future is left incomplete.

Relevant code paths:

- `InvocationChannel.clearExpireContext()` removes expired entries.
- `InvocationContext` owns the waiting response future.
- `LocalServiceManager` schedules periodic `scanAndCleanChannels()`.
- `LocalMessageService.sendMessage()` and `popMessage()` register these invocation contexts.

### Steps to Reproduce

1. Create an `InvocationChannel` and register an `InvocationContext` with a response future.
2. Let the context become older than `channelExpiredInSeconds`.
3. Run channel cleanup through `clearExpireContext()` or `ChannelManager.scanAndCleanChannels()`.
4. Observe that the context is removed but the original response future is still not completed.

### What Did You Expect to See?

When an invocation context is expired and removed by cleanup, its waiting response future should complete exceptionally with a timeout/cleanup error.

### What Did You See Instead?

The invocation context is removed from the channel, but the response future remains pending forever.

### Additional Context

This can leave local proxy callers hanging indefinitely on send/pop operations even after cleanup has already determined that the in-flight request expired.

Contributor guide

Open the contributing guide

Research direction

Start with InvocationChannel.clearExpireContext() and inspect how expired InvocationContext entries are removed. Trace the response futures created by LocalMessageService.sendMessage() and popMessage(), and review LocalServiceManager.scanAndCleanChannels() for the cleanup path. Done means an expired context is removed and its waiting future completes exceptionally with a timeout or cleanup error.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
distributed-systems
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.