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(

Reply via email to