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 ea290419 perf: remove N+1 admin calls from listConsumerGroups (#1446)
ea290419 is described below

commit ea290419bfa415f4bc61d158bf53d5bc0ead2a9b
Author: Yu Xinqiang <[email protected]>
AuthorDate: Tue Aug 11 00:26:38 2026 +0800

    perf: remove N+1 admin calls from listConsumerGroups (#1446)
    
    * [ISSUE #1445] Remove N+1 admin calls from listConsumerGroups
    
    The list operation called enrichGroupWithConnectionInfo for every
    group, making 2 admin API calls per group. For 100 groups this meant
    200 admin calls and minutes-long page load. This fix removes the
    live enrichment from the list, keeping it for the detail page only.
    
    Fixes #1445
    
    * refactor(metadata): drop dead enrichment helper after list de-enrichment
    
    After removing the N+1 enrichment from listConsumerGroups,
    enrichGroupWithConnectionInfo and its dedicated executeForInstance
    helper have no remaining callers: the group detail page loads
    connection and lag info through getGroupSubscriptions and
    getGroupProgress. Remove both helpers along with the test that
    asserted list-time enrichment.
---
 .../provider/apache/RocketMQMetadataProvider.java  | 46 ++--------------------
 .../apache/RocketMQMetadataProviderTest.java       | 16 --------
 2 files changed, 3 insertions(+), 59 deletions(-)

diff --git 
a/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQMetadataProvider.java
 
b/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQMetadataProvider.java
index 31055ae8..da3dea7b 100644
--- 
a/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQMetadataProvider.java
+++ 
b/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQMetadataProvider.java
@@ -182,11 +182,9 @@ public class RocketMQMetadataProvider implements 
MetadataProvider {
             vo.setCreatedAt(entity.getCreatedAt());
             vo.setUpdatedAt(entity.getUpdatedAt());
 
-            if (StringUtils.hasText(instanceId)) {
-                enrichGroupWithConnectionInfo(vo, entity.getName(), 
instanceId);
-            } else if (hasAdmin()) {
-                enrichGroupWithConnectionInfo(vo, entity.getName(), null);
-            }
+            // Live connection info (online instances, lag) is intentionally 
NOT fetched
+            // during list operations to avoid N+1 admin API calls. It is 
loaded on
+            // demand when viewing a single group's detail page.
             result.add(vo);
         }
         return result;
@@ -420,44 +418,6 @@ public class RocketMQMetadataProvider implements 
MetadataProvider {
 
     // ── Helper methods ──────────────────────────────────────────────────
 
-    private void enrichGroupWithConnectionInfo(ConsumerGroupVO vo, String 
groupName, String instanceId) {
-        try {
-            ConsumerConnection conn = executeForInstance(instanceId,
-                    admin -> admin.examineConsumerConnectionInfo(groupName));
-            if (conn != null) {
-                if (conn.getConnectionSet() != null) {
-                    vo.setOnlineInstances(conn.getConnectionSet().size());
-                }
-                if (conn.getSubscriptionTable() != null) {
-                    vo.setSubscribedTopics(new 
ArrayList<>(conn.getSubscriptionTable().keySet()));
-                }
-            }
-        } catch (Exception ignored) {
-            // Group may be offline, that's fine
-        }
-
-        // Try to get lag info
-        try {
-            ConsumeStats stats = executeForInstance(instanceId, admin -> 
admin.examineConsumeStats(groupName));
-            if (stats != null && stats.getOffsetTable() != null) {
-                long totalLag = 0;
-                for (OffsetWrapper ow : stats.getOffsetTable().values()) {
-                    totalLag += Math.max(0, ow.getBrokerOffset() - 
ow.getConsumerOffset());
-                }
-                vo.setTotalLag(totalLag);
-            }
-        } catch (Exception ignored) {
-            // No stats available
-        }
-    }
-
-    private <T> T executeForInstance(String instanceId, 
MqAdminExtFactory.AdminAction<T> action) {
-        if (StringUtils.hasText(instanceId)) {
-            return runtimeAdminClientResolver.execute(instanceId, action);
-        }
-        return adminExecute(action);
-    }
-
     private String filterMode(String expressionType) {
         if ("SQL92".equals(expressionType)) {
             return "SQL";
diff --git 
a/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQMetadataProviderTest.java
 
b/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQMetadataProviderTest.java
index 41def9bc..3259cd90 100644
--- 
a/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQMetadataProviderTest.java
+++ 
b/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQMetadataProviderTest.java
@@ -44,7 +44,6 @@ import static org.mockito.Mockito.lenient;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -103,21 +102,6 @@ class RocketMQMetadataProviderTest {
         
assertThat(groups.get(0).getConsumeType()).isEqualTo(ConsumeType.CLUSTERING);
     }
 
-    @Test
-    void listConsumerGroupsShouldUseSelectedInstanceForRuntimeEnrichment() {
-        RmqGroup entity = new RmqGroup();
-        entity.setName("group-a");
-        entity.setInstanceId("instance-a");
-        entity.setClusterId("cluster-a");
-        when(groupMapper.selectList(any())).thenReturn(List.of(entity));
-        when(runtimeAdminClientResolver.execute(eq("instance-a"), 
any())).thenReturn(null);
-
-        List<ConsumerGroupVO> groups = 
newProvider().listConsumerGroups("instance-a", null, null);
-
-        
assertThat(groups).singleElement().extracting(ConsumerGroupVO::getName).isEqualTo("group-a");
-        verify(runtimeAdminClientResolver, times(2)).execute(eq("instance-a"), 
any());
-    }
-
     @Test
     void getTopicRoutesShouldUseSelectedInstanceRuntimeClient() {
         List<BrokerRouteVO> routes = 
List.of(BrokerRouteVO.builder().brokerName("broker-a").build());

Reply via email to