Skip to content

[Bug] ProxyChannel leaves unsupported RemotingCommand writes permanently pending #10748

Description

@ai-yang

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:

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions