Repository navigation
[ISSUE #11456] fix(proxy): stop the expired-request timer when the remoting server shuts down - #11457
Open
iloveeyjafjalla wants to merge 1 commit into
Open
iloveeyjafjalla wants to merge 1 commit into
iloveeyjafjalla wants to merge 1 commit into
Conversation
…huts down The constructor schedules cleanExpireRequest on a single-thread ScheduledExecutorService created with ThreadFactoryBuilder - whose threads are not daemons - and shutdown() stops the eight remoting executors but not that one. A stopped server therefore keeps a live thread running the 100ms cleanup task, and the non-daemon thread keeps the JVM alive after the context has closed. This is the same shape as the pop-consume service that apache#11428 stopped on the push consumer. Stop it with the rest, and pin the shutdown contract so a new executor cannot be started without also being stopped.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #11457 +/- ##
=============================================
+ Coverage 49.72% 49.74% +0.01%
- Complexity 14366 14367 +1
=============================================
Files 1390 1390
Lines 103264 103265 +1
Branches 13504 13504
=============================================
+ Hits 51351 51369 +18
+ Misses 45707 45691 -16
+ Partials 6206 6205 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
RockteMQ-AI
approved these changes
Oct 20, 2026
RockteMQ-AI
approved these changes
Oct 20, 2026
RockteMQ-AI
left a comment
Contributor
There was a problem hiding this comment.
Review by github-manager-bot
Summary
Fix resource leak: stop the expired-request timer executor during server shutdown.
Findings
- [Info] proxy/src/main/java/org/apache/rocketmq/proxy/remoting/RemotingProtocolServer.java:263 — The fix correctly addresses a resource leak where
timerExecutorwas not shut down, leaving a non-daemon thread running the 100ms cleanup task after server shutdown. This matches the pattern of #11427.
Suggestions
The change is minimal, correct, and well-tested. The new test testShutdownStopsTheExpiredRequestTimer properly verifies the shutdown contract by injecting mocks for all executors and verifying timerExecutor.shutdown() is called exactly once.
Analysis
- Correctness: ✅ The fix is correct — all executors started in the constructor should be stopped in
shutdown() - Resource management: ✅ Prevents non-daemon thread leak that would keep JVM alive after context close
- Test coverage: ✅ Excellent test that pins the entire shutdown contract
- Backward compatibility: ✅ No API changes
LGTM. Clean fix for a legitimate resource leak.
Automated review by github-manager-bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Which Issue(s) This PR Fixes
Fixes #11456
Problem
RemotingProtocolServer's constructor schedulescleanExpireRequeston a single-threadScheduledExecutorServicebuilt withThreadFactoryBuilder(non-daemon threads):shutdown()stops the eight remoting executors and leavestimerExecutorrunning, so a shut-down server keeps a live thread running the 100 ms cleanup task against stopped state, and the non-daemon thread keeps the JVM alive after the context closes. This is the same shape as #11427 (a service created in a constructor that the owner's shutdown never stops).Change
Stop the timer with the other executors:
Verification
RemotingProtocolServerTestgainstestShutdownStopsTheExpiredRequestTimer, which injects mocks for every collaboratorshutdown()touches and verifies the timer is stopped. With the old code:After the change, with JDK 8 (
mvn -B -ntp -pl proxy -am test -Dtest='RemotingProtocolServerTest' -DfailIfNoTests=false -Djacoco.skip=true):The test pins the whole shutdown contract, so a future executor started in this class cannot be added without also being stopped. The change was prepared with AI assistance and reviewed, tested and verified by me.