Skip to content

[ISSUE #10764] Complete expired invocation futures - #10765

Open
Aias00 wants to merge 1 commit into
apache:developfrom
Aias00:fix/proxy-invocation-expire-futures
Open

[ISSUE #10764] Complete expired invocation futures#10765
Aias00 wants to merge 1 commit into
apache:developfrom
Aias00:fix/proxy-invocation-expire-futures

Conversation

@Aias00

@Aias00 Aias00 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Which Issue(s) This PR Fixes

Fixes #10764

Brief Description

InvocationChannel.clearExpireContext() now completes expired invocation contexts exceptionally before removing them from the in-flight request map. This prevents local proxy send/pop callers from waiting forever after cleanup has already expired their request context.

How Did You Test This Change?

  • mvn -pl proxy -Dtest=InvocationChannelTest test

Copilot AI review requested due to automatic review settings August 3, 2026 05:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses RocketMQ Proxy local-mode hangs by ensuring that when InvocationChannel expires and removes in-flight invocation contexts during cleanup, the associated response futures are completed exceptionally instead of being left pending indefinitely.

Changes:

  • Add an expire(Throwable) hook to InvocationContextInterface and implement it in InvocationContext to complete the response future exceptionally.
  • Update InvocationChannel.clearExpireContext() to call expire(...) on expired contexts as they are cleaned up.
  • Add a unit test covering the “cleanup expires context => future completes exceptionally” behavior and initialize proxy configuration for the test class.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
proxy/src/test/java/org/apache/rocketmq/proxy/service/channel/InvocationChannelTest.java Adds coverage ensuring expired cleanup completes the response future exceptionally (and initializes proxy config for the test class).
proxy/src/main/java/org/apache/rocketmq/proxy/service/channel/InvocationContextInterface.java Introduces an expire(Throwable) lifecycle hook for cleanup expiration handling.
proxy/src/main/java/org/apache/rocketmq/proxy/service/channel/InvocationContext.java Implements expire(Throwable) by completing the underlying response CompletableFuture exceptionally.
proxy/src/main/java/org/apache/rocketmq/proxy/service/channel/InvocationChannel.java Completes expired invocation contexts exceptionally during periodic cleanup via clearExpireContext().

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Map.Entry<Integer, InvocationContextInterface> entry = iterator.next();
if (entry.getValue().expired(ConfigurationManager.getProxyConfig().getChannelExpiredInSeconds())) {
iterator.remove();
entry.getValue().expire(new RemotingTimeoutException("Invocation context expired. opaque=" + entry.getKey()));
Comment on lines 25 to +28
boolean expired(long expiredTimeSec);

default void expire(Throwable throwable) {
}
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 48.22%. Comparing base (89166af) to head (a0f9c19).
⚠️ Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
...xy/service/channel/InvocationContextInterface.java 0.00% 1 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             develop   #10765      +/-   ##
=============================================
- Coverage      48.29%   48.22%   -0.07%     
+ Complexity     13499    13483      -16     
=============================================
  Files           1380     1381       +1     
  Lines         101093   101097       +4     
  Branches       13102    13102              
=============================================
- Hits           48821    48756      -65     
- Misses         46304    46353      +49     
- Partials        5968     5988      +20     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review by github-manager-bot

Summary

Adds an expire() method to InvocationContextInterface (default no-op) and implements it in InvocationContext to complete the response future exceptionally with RemotingTimeoutException. InvocationChannel.clearExpireContext() now calls expire() after removing entries, preventing callers from waiting indefinitely on expired invocations.

Findings

  • [Correctness] InvocationChannel.java:71 — The expire() call is placed after iterator.remove(), which is correct. The entry is already removed from the map, and the future is completed exceptionally to unblock any waiting caller.
  • [Correctness] InvocationContext.java:40-43 — The implementation checks responseFuture != null before completing exceptionally, which avoids NPE. Using completeExceptionally is the right choice — callers using whenComplete or exceptionally will properly receive the timeout signal.
  • [Compatibility] InvocationContextInterface.java — Adding expire() as a default method is backward-compatible. Any existing implementations will get the no-op default without breaking.
  • [Tests] InvocationChannelTest.java — New test testClearExpireContextCompletesExpiredFutures verifies that expired futures are completed exceptionally with RemotingTimeoutException. Good coverage.

Verdict

Clean fix for a real hang scenario. Well-structured with proper interface extension. LGTM.


Automated review by github-manager-bot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] InvocationChannel cleanup drops expired local proxy futures

4 participants