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

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


The following commit(s) were added to refs/heads/master by this push:
     new 524ce38  Improve WAGED simulation API by throwing exception on 
FAILED_TO_CALCULATE (#1701)
524ce38 is described below

commit 524ce38b910c599a3ca2e08f3581d20ecc0a12b0
Author: Neal Sun <[email protected]>
AuthorDate: Thu May 6 14:07:24 2021 -0700

    Improve WAGED simulation API by throwing exception on FAILED_TO_CALCULATE 
(#1701)
    
    WAGED simulation API now throws HelixException upon encountering 
FAILED_TO_CALCULATE.
    
    Co-authored-by: Neal Sun <[email protected]>
---
 .../rebalancer/waged/ReadOnlyWagedRebalancer.java  | 12 +++++++++++
 .../rebalancer/waged/WagedRebalancer.java          | 15 +++++++++++---
 .../main/java/org/apache/helix/util/HelixUtil.java |  3 ++-
 .../WagedRebalancer/TestWagedRebalance.java        | 24 ++++++++++++++++++++++
 4 files changed, 50 insertions(+), 4 deletions(-)

diff --git 
a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/ReadOnlyWagedRebalancer.java
 
b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/ReadOnlyWagedRebalancer.java
index 6808389..44a3c1c 100644
--- 
a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/ReadOnlyWagedRebalancer.java
+++ 
b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/ReadOnlyWagedRebalancer.java
@@ -19,9 +19,12 @@ package org.apache.helix.controller.rebalancer.waged;
  * under the License.
  */
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.apache.helix.HelixRebalanceException;
 import 
org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
@@ -48,6 +51,15 @@ public class ReadOnlyWagedRebalancer extends WagedRebalancer 
{
         ConstraintBasedAlgorithmFactory.getInstance(preferences), 
Optional.empty());
   }
 
+  @Override
+  protected List<HelixRebalanceException.Type> failureTypesToPropagate() {
+    // Also propagate FAILED_TO_CALCULATE for ReadOnlyWagedRebalancer
+    List<HelixRebalanceException.Type> failureTypes =
+        new ArrayList<>(super.failureTypesToPropagate());
+    failureTypes.add(HelixRebalanceException.Type.FAILED_TO_CALCULATE);
+    return failureTypes;
+  }
+
   private static class ReadOnlyAssignmentMetadataStore extends 
AssignmentMetadataStore {
     ReadOnlyAssignmentMetadataStore(String metadataStoreAddress, String 
clusterName) {
       super(new ZkBucketDataAccessor(metadataStoreAddress), clusterName);
diff --git 
a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/WagedRebalancer.java
 
b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/WagedRebalancer.java
index 4451c1d..44df28c 100644
--- 
a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/WagedRebalancer.java
+++ 
b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/WagedRebalancer.java
@@ -20,6 +20,7 @@ package org.apache.helix.controller.rebalancer.waged;
  */
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -90,6 +91,10 @@ public class WagedRebalancer implements 
StatefulRebalancer<ResourceControllerDat
   private static final RebalanceAlgorithm DEFAULT_REBALANCE_ALGORITHM =
       ConstraintBasedAlgorithmFactory
           .getInstance(ClusterConfig.DEFAULT_GLOBAL_REBALANCE_PREFERENCE);
+  // These failure types should be propagated to caller of 
computeNewIdealStates()
+  private static final List<HelixRebalanceException.Type> 
FAILURE_TYPES_TO_PROPAGATE = Collections
+      
.unmodifiableList(Arrays.asList(HelixRebalanceException.Type.INVALID_REBALANCER_STATUS,
+          HelixRebalanceException.Type.UNKNOWN_FAILURE));
 
   // To calculate the baseline asynchronously
   private final ExecutorService _baselineCalculateExecutor;
@@ -268,12 +273,12 @@ public class WagedRebalancer implements 
StatefulRebalancer<ResourceControllerDat
       _rebalanceFailureCount.increment(1L);
 
       HelixRebalanceException.Type failureType = ex.getFailureType();
-      if 
(failureType.equals(HelixRebalanceException.Type.INVALID_REBALANCER_STATUS) || 
failureType
-          .equals(HelixRebalanceException.Type.UNKNOWN_FAILURE)) {
+      if (failureTypesToPropagate().contains(failureType)) {
         // If the failure is unknown or because of assignment store access 
failure, throw the
         // rebalance exception.
         throw ex;
-      } else { // return the previously calculated assignment.
+      } else {
+        // return the previously calculated assignment.
         LOG.warn(
             "Returning the last known-good best possible assignment from 
metadata store due to "
                 + "rebalance failure of type: {}", failureType);
@@ -393,6 +398,10 @@ public class WagedRebalancer implements 
StatefulRebalancer<ResourceControllerDat
     return finalIdealStateMap;
   }
 
+  protected List<HelixRebalanceException.Type> failureTypesToPropagate() {
+    return FAILURE_TYPES_TO_PROPAGATE;
+  }
+
   /**
    * Global rebalance calculates for a new baseline assignment.
    * The new baseline assignment will be persisted and leveraged by the 
partial rebalance.
diff --git a/helix-core/src/main/java/org/apache/helix/util/HelixUtil.java 
b/helix-core/src/main/java/org/apache/helix/util/HelixUtil.java
index 7fb5bc1..38103e9 100644
--- a/helix-core/src/main/java/org/apache/helix/util/HelixUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/util/HelixUtil.java
@@ -296,7 +296,8 @@ public final class HelixUtil {
     // Convert the resulting BestPossibleStateOutput to Map<String, 
ResourceAssignment>
     Map<String, ResourceAssignment> result = new HashMap<>();
     BestPossibleStateOutput output = 
event.getAttribute(AttributeName.BEST_POSSIBLE_STATE.name());
-    if (output == null) {
+    if (output == null || (output.getPreferenceLists() == null && 
output.getResourceStatesMap()
+        .isEmpty())) {
       throw new HelixException(
           "getIdealAssignmentForWagedFullAuto(): Calculation failed: Failed to 
compute BestPossibleState!");
     }
diff --git 
a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/WagedRebalancer/TestWagedRebalance.java
 
b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/WagedRebalancer/TestWagedRebalance.java
index bb58d86..a7250d4 100644
--- 
a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/WagedRebalancer/TestWagedRebalance.java
+++ 
b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/WagedRebalancer/TestWagedRebalance.java
@@ -31,6 +31,7 @@ import java.util.Set;
 import com.google.common.collect.ImmutableMap;
 import org.apache.helix.ConfigAccessor;
 import org.apache.helix.HelixDataAccessor;
+import org.apache.helix.HelixException;
 import org.apache.helix.TestHelper;
 import org.apache.helix.common.ZkTestBase;
 import 
org.apache.helix.controller.rebalancer.strategy.CrushEdRebalanceStrategy;
@@ -275,6 +276,29 @@ public class TestWagedRebalance extends ZkTestBase {
       // The newly added instances should contain some partitions
       
Assert.assertTrue(instancesWithAssignmentsImmediate.contains(instance_0));
       
Assert.assertTrue(instancesWithAssignmentsImmediate.contains(instance_1));
+
+      // Force FAILED_TO_CALCULATE and ensure that both util functions return 
no mappings
+      String testCapacityKey = "key";
+      
clusterConfig.setDefaultPartitionWeightMap(Collections.singletonMap(testCapacityKey,
 2));
+      
clusterConfig.setDefaultInstanceCapacityMap(Collections.singletonMap(testCapacityKey,
 1));
+      
clusterConfig.setInstanceCapacityKeys(Collections.singletonList(testCapacityKey));
+      try {
+        HelixUtil.getTargetAssignmentForWagedFullAuto(ZK_ADDR, clusterConfig, 
instanceConfigs,
+            liveInstances, idealStates, resourceConfigs);
+        Assert.fail("Expected HelixException for calculaation failure");
+      } catch (HelixException e) {
+        Assert.assertEquals(e.getMessage(),
+            "getIdealAssignmentForWagedFullAuto(): Calculation failed: Failed 
to compute BestPossibleState!");
+      }
+
+      try {
+        HelixUtil.getImmediateAssignmentForWagedFullAuto(ZK_ADDR, 
clusterConfig, instanceConfigs,
+            liveInstances, idealStates, resourceConfigs);
+        Assert.fail("Expected HelixException for calculaation failure");
+      } catch (HelixException e) {
+        Assert.assertEquals(e.getMessage(),
+            "getIdealAssignmentForWagedFullAuto(): Calculation failed: Failed 
to compute BestPossibleState!");
+      }
     } finally {
       // restore the config with async mode
       clusterConfigGlobal =

Reply via email to