This is an automated email from the ASF dual-hosted git repository.
jackie 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 078117e67e Fix bug when evaluating resource status during service
startup check (#13541)
078117e67e is described below
commit 078117e67ef8da454850791c4ebbbb2bdf37998c
Author: Christopher Peck <[email protected]>
AuthorDate: Tue Aug 6 14:08:30 2024 -0700
Fix bug when evaluating resource status during service startup check
(#13541)
---
.../apache/pinot/common/utils/ServiceStatus.java | 25 +++++++++++++++--
.../pinot/common/utils/ServiceStatusTest.java | 31 +++++++++++++++++++---
2 files changed, 51 insertions(+), 5 deletions(-)
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/utils/ServiceStatus.java
b/pinot-common/src/main/java/org/apache/pinot/common/utils/ServiceStatus.java
index 21ebd1fe21..3731d3b23d 100644
---
a/pinot-common/src/main/java/org/apache/pinot/common/utils/ServiceStatus.java
+++
b/pinot-common/src/main/java/org/apache/pinot/common/utils/ServiceStatus.java
@@ -434,6 +434,26 @@ public class ServiceStatus {
return new StatusDescriptionPair(Status.GOOD, STATUS_DESCRIPTION_NONE);
}
+ // Get ideal state partitions for all instances
+ Map<String, Map<String, String>> idealStateMapFields =
idealState.getRecord().getMapFields();
+ if (idealStateMapFields == null || idealStateMapFields.isEmpty()) {
+ return new StatusDescriptionPair(Status.GOOD,
STATUS_DESCRIPTION_NONE); // Resource has no partitions
+ }
+
+ // Collect all partitions that are assigned to this instance
+ Map<String, String> instanceStateMap = new HashMap<>();
+ for (Map.Entry<String, Map<String, String>> partition :
idealStateMapFields.entrySet()) {
+ if (partition.getValue().containsKey(_instanceName)) {
+ instanceStateMap.put(partition.getKey(),
partition.getValue().get(_instanceName));
+ }
+ }
+
+ // Resource has no partitions assigned to this instance, so the resource
status is GOOD
+ if (instanceStateMap.isEmpty()) {
+ return new StatusDescriptionPair(Status.GOOD, STATUS_DESCRIPTION_NONE);
+ }
+
+ // Null EV or CS, when resource has assigned partitions, means that the
service status is STARTING
T helixState = getState(resourceName);
if (helixState == null) {
return new StatusDescriptionPair(Status.STARTING,
STATUS_DESCRIPTION_NO_HELIX_STATE);
@@ -443,8 +463,9 @@ public class ServiceStatus {
// external view or went to ERROR state (which means that we tried to
load the segments/resources but failed for
// some reason)
Map<String, String> partitionStateMap = getPartitionStateMap(helixState);
- for (String partitionName : idealState.getPartitionSet()) {
- String idealStateStatus =
idealState.getInstanceStateMap(partitionName).get(_instanceName);
+ for (Map.Entry<String, String> entry : instanceStateMap.entrySet()) {
+ String partitionName = entry.getKey();
+ String idealStateStatus = entry.getValue();
// Skip this partition if it is not assigned to this instance or if
the instance should be offline
if (idealStateStatus == null || "OFFLINE".equals(idealStateStatus)) {
diff --git
a/pinot-common/src/test/java/org/apache/pinot/common/utils/ServiceStatusTest.java
b/pinot-common/src/test/java/org/apache/pinot/common/utils/ServiceStatusTest.java
index a214f17f51..1c9c939e08 100644
---
a/pinot-common/src/test/java/org/apache/pinot/common/utils/ServiceStatusTest.java
+++
b/pinot-common/src/test/java/org/apache/pinot/common/utils/ServiceStatusTest.java
@@ -28,6 +28,7 @@ import java.util.Random;
import org.apache.helix.HelixManager;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.mockito.Mockito;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
@@ -134,9 +135,33 @@ public class ServiceStatusTest {
callback.setExternalView(new ExternalView(TABLE_NAME));
assertEquals(callback.getServiceStatus(), ServiceStatus.Status.GOOD);
- // No external view = STARTING
+ // No external view, and ideal state shows this instance is assigned a
segment of the resource = STARTING
callback = buildTestISEVCallback();
- callback.setIdealState(new IdealState(TABLE_NAME));
+ ZNRecord znRecord = new ZNRecord(TABLE_NAME);
+ znRecord.setSimpleField("REBALANCE_MODE", "CUSTOMIZED");
+ znRecord.setMapField("segment1", Map.of(INSTANCE_NAME, "ONLINE"));
+ callback.setIdealState(new IdealState(znRecord));
+ assertEquals(callback.getServiceStatus(), ServiceStatus.Status.STARTING);
+
+ // No external view, and ideal state shows this instance is not assigned a
segment of the resource = GOOD
+ callback = buildTestISEVCallback();
+ znRecord = new ZNRecord(TABLE_NAME);
+ znRecord.setSimpleField("REBALANCE_MODE", "CUSTOMIZED");
+ znRecord.setMapField("segment1", Map.of("otherServerInstance", "ONLINE"));
+ callback.setIdealState(new IdealState(znRecord));
+ assertEquals(callback.getServiceStatus(), ServiceStatus.Status.GOOD);
+
+ // Online ideal state, and external view shows second segment is still
offline = STARTING
+ callback = buildTestISEVCallback();
+ znRecord = new ZNRecord(TABLE_NAME);
+ znRecord.setSimpleField("REBALANCE_MODE", "CUSTOMIZED");
+ znRecord.setMapField("segment1", Map.of(INSTANCE_NAME, "ONLINE"));
+ znRecord.setMapField("segment2", Map.of(INSTANCE_NAME, "ONLINE"));
+ callback.setIdealState(new IdealState(znRecord));
+ ExternalView externalView = new ExternalView(TABLE_NAME);
+ externalView.setState("segment1", INSTANCE_NAME, "ONLINE");
+ externalView.setState("segment2", INSTANCE_NAME, "OFFLINE");
+ callback.setExternalView(externalView);
assertEquals(callback.getServiceStatus(), ServiceStatus.Status.STARTING);
// Empty ideal state + empty external view = GOOD
@@ -170,7 +195,7 @@ public class ServiceStatusTest {
idealState.setPartitionState("mySegment_1", INSTANCE_NAME, "ONLINE");
idealState.setPartitionState("mySegment_2", INSTANCE_NAME, "OFFLINE");
callback.setIdealState(idealState);
- ExternalView externalView = new ExternalView(TABLE_NAME);
+ externalView = new ExternalView(TABLE_NAME);
externalView.setState("mySegment_1", INSTANCE_NAME, "ONLINE");
callback.setExternalView(externalView);
assertEquals(callback.getServiceStatus(), ServiceStatus.Status.GOOD);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]