apache / apache/rocketmq

[Bug] ProxyChannel leaves unsupported RemotingCommand writes permanently pending

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

Description

## Affected branch

`develop` at `a06836dd564e5e43115493f775626cf98d51d10e`.

## Problem

`ProxyChannel.writeAndFlush` creates an incomplete `processFuture` before dispatching a message. For a `RemotingCommand` whose request code is not one of the explicitly supported switch cases, the `default` branch only executes `break`.

The method then attaches completion handlers to the original, still-incomplete `processFuture`. Nothing retains or completes that future, so the returned `ChannelFuture` remains pending forever.

## Deterministic reproduction

A unit test writes a command with the deliberately unassigned sentinel code `Integer.MAX_VALUE` and immediately checks the returned future. The test also requires the eventual failure to unwrap to an `UnsupportedOperationException` containing the request code and verifies that the relay service was not invoked.

The unmodified branch failed identically in 5/5 isolated JDK 8 Maven processes:

```text
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
java.lang.AssertionError: unsupported command future should be completed
```

The test has no network, sleep, timer, or scheduling dependency.

## Impact

The pending write future prevents Netty write listeners from running:

- one-way invocations do not release their semaphore permit;
- synchronous and asynchronous invocations cannot immediately enter their send-failure cleanup path and instead remain until timeout processing;
- callers cannot distinguish an unsupported command from a slow or lost write.

Repeated unsupported one-way writes can exhaust the one-way semaphore.

## Expected behavior

An unsupported `RemotingCommand` should produce an immediately completed failed `ChannelFuture`, with a diagnostic exception that identifies the unsupported request code. It must not report success because no message was delivered.

## Suggested fix

Complete `processFuture` exceptionally in the switch `default` branch, for example with:

```java
new UnsupportedOperationException(
"Unsupported remoting command code: " + command.getCode())
```

This preserves all supported command paths while allowing existing write listeners to release resources and apply their normal failure handling.

## Related work checked

Searches covered open and closed issues, and open, closed, and merged pull requests, using `ProxyChannel`, `ChannelFuture`, pending writes, unsupported commands, and the expected file.

- #7199 and #7728 concern an NPE in the explicit `GET_CONSUMER_RUNNING_INFO` path.
- Open PR #10480 adds cluster-mode support for that explicit request and touches `ProxyChannelTest`, but does not change the switch default or pending-future behavior.
- No equivalent report, implementation, assignee, or maintainer handoff was found.

Contributor guide

Open the contributing guide

Research direction

Start in ProxyChannel.writeAndFlush and inspect the switch handling RemotingCommand request codes, then review the related ProxyChannelTest scenario described in the issue. Run the deterministic unsupported-command test with Integer.MAX_VALUE; done means the returned ChannelFuture fails immediately with an UnsupportedOperationException naming the code, and the relay service is not invoked.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, networking
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.