xiangfu0 commented on code in PR #19997:
URL: https://github.com/apache/pinot/pull/19997#discussion_r4343901811
##########
pinot-broker/src/test/java/org/apache/pinot/broker/routing/manager/BrokerRoutingManagerTest.java:
##########
@@ -860,6 +860,36 @@ public void
testRoutableServerInstanceMapReflectsExclusion() {
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));
Review Comment:
Good targeted regression test — I confirmed it fails on the pre-fix code and
passes here. The `onInstancesChange(Set.of(healthyServer),
List.of(SERVER_INSTANCE_ID))` assertion pins down both the routable set and the
exact changed list, which is what the bug corrupted. Minor optional nit: a
one-line comment that the routing entry is added *after* the exclusion (so this
verify captures only the shutdown-triggered callback, not the earlier exclusion
one) would save the next reader a moment of head-scratching.
##########
pinot-broker/src/main/java/org/apache/pinot/broker/routing/manager/BaseBrokerRoutingManager.java:
##########
@@ -486,21 +486,14 @@ private void processInstanceConfigChangeInternal() {
}
}
- // 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);
Review Comment:
Nice simplification. `removeAll` is now called unconditionally, which is a
no-op when `_excludedServers` is empty, so the two branches collapse cleanly
with no behavior change for the common case. The added NOTE explaining *why*
excluded disabled servers are still counted (to keep the early return from
skipping their removal) is exactly the context a future reader needs. No change
requested.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]