This is an automated email from the ASF dual-hosted git repository.
RongtongJin pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/rocketmq.git
The following commit(s) were added to refs/heads/develop by this push:
new 38a7ca0d23 [ISSUE #11477] fix(container): stop the container scheduler
when the broker container shuts down
38a7ca0d23 is described below
commit 38a7ca0d23a3e2d4339f9a2bf6e78cf541eed9e3
Author: bai mengxuan <[email protected]>
AuthorDate: Thu Oct 22 17:22:47 2026 +0800
[ISSUE #11477] fix(container): stop the container scheduler when the broker
container shuts down
BrokerContainer.initialize() schedules the name-server refresh and the
five-second
brokerOuterAPI.refreshMetadata() task on scheduledExecutorService, and
shutdown()
stops the brokers, both remoting servers, the request executor and the
outer API -
but not that scheduler. A shut-down container therefore keeps refreshing
metadata
through an API it has already closed, logging "ScheduledTask refresh
metadata
exception" every five seconds, and leaks the scheduler thread on every
start/shutdown
cycle. Stop it before the API is closed, the way the request executor next
to it is
stopped.
---
.../apache/rocketmq/container/BrokerContainer.java | 4 ++++
.../rocketmq/container/BrokerContainerTest.java | 19 +++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git
a/container/src/main/java/org/apache/rocketmq/container/BrokerContainer.java
b/container/src/main/java/org/apache/rocketmq/container/BrokerContainer.java
index e8debfe99b..5c7c69296a 100644
--- a/container/src/main/java/org/apache/rocketmq/container/BrokerContainer.java
+++ b/container/src/main/java/org/apache/rocketmq/container/BrokerContainer.java
@@ -245,6 +245,10 @@ public class BrokerContainer implements IBrokerContainer {
// Shutdown the request executors
ThreadUtils.shutdown(this.brokerContainerExecutor);
+ // Stop the periodic tasks (name-server refresh and the five-second
metadata refresh) before
+ // the API they call is closed, so nothing of the container keeps
running after shutdown.
+ ThreadUtils.shutdown(this.scheduledExecutorService);
+
if (this.brokerOuterAPI != null) {
this.brokerOuterAPI.shutdown();
}
diff --git
a/container/src/test/java/org/apache/rocketmq/container/BrokerContainerTest.java
b/container/src/test/java/org/apache/rocketmq/container/BrokerContainerTest.java
index f53741aa3f..d7c87d632c 100644
---
a/container/src/test/java/org/apache/rocketmq/container/BrokerContainerTest.java
+++
b/container/src/test/java/org/apache/rocketmq/container/BrokerContainerTest.java
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
import org.apache.rocketmq.broker.BrokerController;
import org.apache.rocketmq.broker.ConfigContext;
import org.apache.rocketmq.broker.out.BrokerOuterAPI;
@@ -77,6 +78,24 @@ public class BrokerContainerTest {
brokerController.shutdown();
}
+ @Test
+ public void testShutdownStopsTheScheduledExecutorTest() throws Exception {
+ BrokerContainer brokerContainer = new BrokerContainer(
+ new BrokerContainerConfig(),
+ new NettyServerConfig(),
+ new NettyClientConfig());
+ assertThat(brokerContainer.initialize()).isTrue();
+ Field field =
BrokerContainer.class.getDeclaredField("scheduledExecutorService");
+ field.setAccessible(true);
+ ScheduledExecutorService scheduledExecutorService =
(ScheduledExecutorService) field.get(brokerContainer);
+
+ brokerContainer.shutdown();
+
+ // initialize() schedules the five-second refreshMetadata task on this
executor; a shutdown
+ // that leaves it running keeps calling the brokerOuterAPI after it
has been closed.
+ assertThat(scheduledExecutorService.isShutdown()).isTrue();
+ }
+
@Test
public void testRegisterIncrementBrokerData() throws Exception {
BrokerController brokerController = new BrokerController(