This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new 613c3b675 fix(lite): keep the LiteTopic list and quota pages up when 
one master fails (#4566)
613c3b675 is described below

commit 613c3b675091ff74c600b87c693cdde0523e2011
Author: 烤化の初雪 <[email protected]>
AuthorDate: Thu Sep 24 17:45:04 2026 +0800

    fix(lite): keep the LiteTopic list and quota pages up when one master fails 
(#4566)
    
    fix(lite): keep the LiteTopic list and quota pages up when one master fails
    
    getBrokerLiteInfo was the only per-master read in the provider without
    a catch, so one unreachable or pre-lite master failed the whole admin
    action and surfaced as a 502 for the entire list and quota pages even
    when every other master answered. Skip the failing master and aggregate
    the reachable ones, matching the degradation every sibling read in the
    file already applies.
    
    Fixes #4565.
---
 .../provider/apache/RocketMQLiteTopicProvider.java | 21 ++++++++++-
 .../apache/RocketMQLiteTopicProviderTest.java      | 44 ++++++++++++++++++++++
 2 files changed, 63 insertions(+), 2 deletions(-)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProvider.java
 
b/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProvider.java
index cfae98e34..73042a056 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProvider.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProvider.java
@@ -162,7 +162,16 @@ public class RocketMQLiteTopicProvider implements 
LiteTopicProvider {
             throws Exception {
         Map<String, ParentTopicAccumulator> parents = new LinkedHashMap<>();
         for (String master : masters) {
-            GetBrokerLiteInfoResponseBody info = 
admin.getBrokerLiteInfo(master);
+            final GetBrokerLiteInfoResponseBody info;
+            try {
+                info = admin.getBrokerLiteInfo(master);
+            } catch (Exception failure) {
+                // Every other per-master read in this provider degrades 
instead of failing
+                // the page; a single unreachable (or pre-lite) master must 
not turn the
+                // whole list into a 502 when its peers still answer.
+                log.warn("Skipping master {} for the LiteTopic list: {}", 
master, failure.getMessage());
+                continue;
+            }
             if (info == null || info.getTopicMeta() == null) {
                 continue;
             }
@@ -422,7 +431,15 @@ public class RocketMQLiteTopicProvider implements 
LiteTopicProvider {
             long currentSessions = 0;
             long maxSessions = 0;
             for (String master : masters) {
-                GetBrokerLiteInfoResponseBody info = 
admin.getBrokerLiteInfo(master);
+                final GetBrokerLiteInfoResponseBody info;
+                try {
+                    info = admin.getBrokerLiteInfo(master);
+                } catch (Exception failure) {
+                    // Same per-master degradation as the list path: one 
unreachable or
+                    // pre-lite master must not fail the whole quota page with 
a 502.
+                    log.warn("Skipping master {} for the LiteTopic quota: {}", 
master, failure.getMessage());
+                    continue;
+                }
                 if (info == null) {
                     // Skip the master entirely: adding its session cap 
without its current
                     // counts would build the ratio out of two different 
master sets.
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProviderTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProviderTest.java
index a6518fd88..009edba67 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProviderTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProviderTest.java
@@ -124,6 +124,50 @@ class RocketMQLiteTopicProviderTest {
         assertThat(provider.isSupported()).isTrue();
     }
 
+    @Test
+    void listLiteTopicsSkipsAMasterWhoseLiteInfoFailsInsteadOfFailingThePage() 
throws Exception {
+        String failingMaster = "127.0.0.1:10912";
+        when(admin.examineBrokerClusterInfo()).thenReturn(cluster(BROKER_A, 
failingMaster));
+        
when(admin.getBrokerLiteInfo(BROKER_A)).thenReturn(brokerLiteInfo(PARENT, 30, 
2, GROUP));
+        when(admin.getBrokerLiteInfo(failingMaster))
+                .thenThrow(new IllegalStateException("broker restarting"));
+        when(admin.getParentTopicInfo(BROKER_A, 
PARENT)).thenReturn(parentTopicInfo(PARENT, 30, 2));
+        when(admin.getLiteGroupInfo(BROKER_A, GROUP, null, 
1)).thenReturn(lag(7));
+        
when(admin.examineConsumerConnectionInfo(GROUP)).thenReturn(consumerConnection("c1",
 "10.0.0.9:1234"));
+        when(admin.getLiteClientInfo(BROKER_A, PARENT, GROUP, 
"c1")).thenReturn(clientInfo(2, System.currentTimeMillis()));
+
+        List<LiteTopicSummary> summaries = provider.listLiteTopics(null, null);
+
+        assertThat(summaries).singleElement().satisfies(summary -> {
+            assertThat(summary.getTopicPattern()).isEqualTo(PARENT);
+            assertThat(summary.getTopicCount()).isEqualTo(2);
+            assertThat(summary.getTotalBacklog()).isEqualTo(7L);
+        });
+    }
+
+    @Test
+    void quotaSkipsAMasterWhoseLiteInfoFailsInsteadOfFailingThePage() throws 
Exception {
+        String failingMaster = "127.0.0.1:10912";
+        when(admin.examineBrokerClusterInfo()).thenReturn(cluster(BROKER_A, 
failingMaster));
+        when(admin.getBrokerLiteInfo(BROKER_A)).thenReturn(brokerLiteInfo(3, 
40, 3));
+        when(admin.getBrokerLiteInfo(failingMaster))
+                .thenThrow(new IllegalStateException("broker restarting"));
+        Properties reachableConfig = new Properties();
+        reachableConfig.setProperty("maxLiteSubscriptionCount", "100000");
+        when(admin.getBrokerConfig(BROKER_A)).thenReturn(reachableConfig);
+        Properties failingConfig = new Properties();
+        failingConfig.setProperty("maxLiteSubscriptionCount", "100000");
+        when(admin.getBrokerConfig(failingMaster)).thenReturn(failingConfig);
+
+        LiteTopicQuota quota = provider.getQuota(null);
+
+        // Only the reachable master contributed counts, so the ratio is built 
from it alone.
+        assertThat(quota.getCurrentTopicCount()).isEqualTo(3);
+        assertThat(quota.getMaxTopicCount()).isEqualTo(40);
+        assertThat(quota.getCurrentSessionCount()).isEqualTo(3);
+        assertThat(quota.getMaxSessionCount()).isEqualTo(100_000);
+    }
+
     @Test
     void listLiteTopicsAggregatesParentTopicTtlBacklogAndSessions() throws 
Exception {
         long lastAccess = System.currentTimeMillis() - 1_000;

Reply via email to