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

yashmayya pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new b02a7651269 Fix broker routing ignoring a shutting down server while 
another server is excluded (#19997)
b02a7651269 is described below

commit b02a76512697ff971368d1c1e23be91d8da8bd23
Author: Yash Mayya <[email protected]>
AuthorDate: Thu Oct 22 11:38:22 2026 -0700

    Fix broker routing ignoring a shutting down server while another server is 
excluded (#19997)
---
 .../routing/manager/BaseBrokerRoutingManager.java  | 21 +++++----------
 .../routing/manager/BrokerRoutingManagerTest.java  | 30 ++++++++++++++++++++++
 2 files changed, 37 insertions(+), 14 deletions(-)

diff --git 
a/pinot-broker/src/main/java/org/apache/pinot/broker/routing/manager/BaseBrokerRoutingManager.java
 
b/pinot-broker/src/main/java/org/apache/pinot/broker/routing/manager/BaseBrokerRoutingManager.java
index bb28278db52..6503606f600 100644
--- 
a/pinot-broker/src/main/java/org/apache/pinot/broker/routing/manager/BaseBrokerRoutingManager.java
+++ 
b/pinot-broker/src/main/java/org/apache/pinot/broker/routing/manager/BaseBrokerRoutingManager.java
@@ -486,21 +486,14 @@ public abstract class BaseBrokerRoutingManager
       }
     }
 
-    // Calculate the routable servers and the changed routable servers
+    // Calculate the routable servers and the changed servers
+    // NOTE: All new enabled servers are routable because they are removed 
from the excluded servers above. All new
+    //       disabled servers are counted as changed, even excluded ones whose 
routing does not change, so that the
+    //       early termination below cannot skip removing them from 
_enabledServerInstanceMap.
     List<String> changedServers = new ArrayList<>(newEnabledServers.size() + 
newDisabledServers.size());
-    if (_excludedServers.isEmpty()) {
-      changedServers.addAll(newEnabledServers);
-      changedServers.addAll(newDisabledServers);
-    } else {
-      enabledServers.removeAll(_excludedServers);
-      // NOTE: All new enabled servers are routable
-      changedServers.addAll(newEnabledServers);
-      for (String newDisabledServer : newDisabledServers) {
-        if (_excludedServers.contains(newDisabledServer)) {
-          changedServers.add(newDisabledServer);
-        }
-      }
-    }
+    changedServers.addAll(newEnabledServers);
+    changedServers.addAll(newDisabledServers);
+    enabledServers.removeAll(_excludedServers);
     _routableServerInstanceMap = 
buildRoutableServerInstanceMap(enabledServers);
     long calculateChangedServersEndTimeMs = System.currentTimeMillis();
 
diff --git 
a/pinot-broker/src/test/java/org/apache/pinot/broker/routing/manager/BrokerRoutingManagerTest.java
 
b/pinot-broker/src/test/java/org/apache/pinot/broker/routing/manager/BrokerRoutingManagerTest.java
index e82fac469fc..4bbd9d88535 100644
--- 
a/pinot-broker/src/test/java/org/apache/pinot/broker/routing/manager/BrokerRoutingManagerTest.java
+++ 
b/pinot-broker/src/test/java/org/apache/pinot/broker/routing/manager/BrokerRoutingManagerTest.java
@@ -860,6 +860,36 @@ public class BrokerRoutingManagerTest {
     
assertTrue(_routingManager.getRoutableServerInstanceMap().containsKey(SERVER_INSTANCE_ID));
   }
 
+  @Test
+  public void 
testShuttingDownServerRemovedFromRoutingWhileAnotherServerIsExcluded()
+      throws Exception {
+    // Enable three servers, then exclude one of them (simulating 
FailureDetector marking it unhealthy)
+    String excludedServer = "Server_excludedhost_8000";
+    String healthyServer = "Server_healthyhost_8000";
+    ZNRecord serverConfig = createEnabledServerZNRecord(SERVER_INSTANCE_ID);
+    ZNRecord excludedServerConfig = 
createEnabledServerZNRecord(excludedServer);
+    ZNRecord healthyServerConfig = createEnabledServerZNRecord(healthyServer);
+    when(_zkDataAccessor.getChildren(eq(INSTANCE_CONFIGS_PATH), any(), 
eq(AccessOption.PERSISTENT), anyInt(), anyInt()))
+        .thenReturn(List.of(serverConfig, excludedServerConfig, 
healthyServerConfig));
+    _routingManager.processClusterChange(ChangeType.INSTANCE_CONFIG);
+    _routingManager.excludeServerFromRouting(excludedServer);
+    InstanceSelector instanceSelector = mock(InstanceSelector.class);
+    putRoutingEntry(TEST_TABLE, createRoutingEntry(TEST_TABLE, null, null, 
Map.of(), instanceSelector, false));
+
+    // The server starts shutting down while the other server is still excluded
+    ZNRecord shuttingDownServerConfig = 
createEnabledServerZNRecord(SERVER_INSTANCE_ID);
+    shuttingDownServerConfig.setSimpleField(Helix.IS_SHUTDOWN_IN_PROGRESS, 
"true");
+    when(_zkDataAccessor.getChildren(eq(INSTANCE_CONFIGS_PATH), any(), 
eq(AccessOption.PERSISTENT), anyInt(), anyInt()))
+        .thenReturn(List.of(shuttingDownServerConfig, excludedServerConfig, 
healthyServerConfig));
+    _routingManager.processClusterChange(ChangeType.INSTANCE_CONFIG);
+
+    // The routing entry must stop selecting the shutting down server, and 
only the healthy server stays routable
+    verify(instanceSelector).onInstancesChange(Set.of(healthyServer), 
List.of(SERVER_INSTANCE_ID));
+    assertEquals(_routingManager.getRoutableServerInstanceMap().keySet(), 
Set.of(healthyServer));
+    // The excluded server stays enabled
+    assertEquals(_routingManager.getEnabledServerInstanceMap().keySet(), 
Set.of(excludedServer, healthyServer));
+  }
+
   @Test
   public void testPartitionPruningThresholdUpdates()
       throws Exception {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to