You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by xy...@apache.org on 2023/07/13 21:16:36 UTC

[helix] branch metaclient updated: MultiThreading Stress Test Lattice - Puppy Logic and Skeleton (Part 1) (#2549)

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

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


The following commit(s) were added to refs/heads/metaclient by this push:
     new 33794e4d3 MultiThreading Stress Test Lattice - Puppy Logic and Skeleton (Part 1) (#2549)
33794e4d3 is described below

commit 33794e4d338001dd4f54df70a5b20dab312b1674
Author: Marcos Rico Peng <55...@users.noreply.github.com>
AuthorDate: Thu Jul 13 17:16:30 2023 -0400

    MultiThreading Stress Test Lattice - Puppy Logic and Skeleton (Part 1) (#2549)
    
    ---------
    
    Co-authored-by: mapeng <ma...@linkedin.com>
---
 .../helix/metaclient/puppy/AbstractPuppy.java      | 95 ++++++++++++++++++++++
 .../apache/helix/metaclient/puppy/ExecDelay.java   | 63 ++++++++++++++
 .../helix/metaclient/puppy/PuppyManager.java       | 64 +++++++++++++++
 .../apache/helix/metaclient/puppy/PuppyMode.java   | 28 +++++++
 .../apache/helix/metaclient/puppy/PuppySpec.java   | 53 ++++++++++++
 5 files changed, 303 insertions(+)

diff --git a/meta-client/src/test/java/org/apache/helix/metaclient/puppy/AbstractPuppy.java b/meta-client/src/test/java/org/apache/helix/metaclient/puppy/AbstractPuppy.java
new file mode 100644
index 000000000..85137fc17
--- /dev/null
+++ b/meta-client/src/test/java/org/apache/helix/metaclient/puppy/AbstractPuppy.java
@@ -0,0 +1,95 @@
+package org.apache.helix.metaclient.puppy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.helix.metaclient.api.MetaClientInterface;
+import java.util.HashMap;
+
+/**
+ * AbstractPuppy object contains interfaces to implement puppy and main logics to manage puppy life cycle
+ */
+public abstract class AbstractPuppy implements Runnable {
+
+  protected MetaClientInterface<String> _metaclient;
+  protected PuppySpec _puppySpec;
+  public HashMap<String, Integer> _eventChangeCounterMap;
+  protected int _unhandledErrorCounter;
+
+  public AbstractPuppy(MetaClientInterface<String> metaclient, PuppySpec puppySpec) {
+    _metaclient = metaclient;
+    _puppySpec = puppySpec;
+    _eventChangeCounterMap = new HashMap<>();
+  }
+
+  /**
+   * Implements puppy's main logic. Puppy needs to implement its chaos logic, recovery logic based on
+   * errorRate, recoverDelay. For OneOff puppy, it will bark once with execDelay in spec, and for
+   * Repeat puppy, it will bark forever, with execDelay between 2 barks
+   */
+  protected abstract void bark() throws Exception;
+
+  /**
+   * Implements puppy's final cleanup logic - it will be called only once right before the puppy terminates.
+   * Before the puppy terminates, it needs to recover from all chaos it created.
+   */
+  protected abstract void cleanup();
+
+  @Override
+  public void run() {
+    try {
+      while (true) {
+        try {
+          bark();
+        } catch (Exception e) {
+          incrementUnhandledErrorCounter();
+          e.printStackTrace();
+        }
+
+        if (getPuppySpec().getMode() == PuppyMode.ONE_OFF) {
+          cleanup();
+          break;
+        } else {
+          try {
+            Thread.sleep(getPuppySpec().getExecDelay().getNextDelay());
+          } catch (InterruptedException e) {
+            // Handle interruption if necessary
+          }
+        }
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  public PuppySpec getPuppySpec() {
+    return _puppySpec;
+  }
+
+  public int getUnhandledErrorCounter() {
+    return _unhandledErrorCounter;
+  }
+
+  private void incrementUnhandledErrorCounter() {
+    _unhandledErrorCounter++;
+  }
+}
+
+
+
diff --git a/meta-client/src/test/java/org/apache/helix/metaclient/puppy/ExecDelay.java b/meta-client/src/test/java/org/apache/helix/metaclient/puppy/ExecDelay.java
new file mode 100644
index 000000000..da0bc529a
--- /dev/null
+++ b/meta-client/src/test/java/org/apache/helix/metaclient/puppy/ExecDelay.java
@@ -0,0 +1,63 @@
+package org.apache.helix.metaclient.puppy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Random;
+
+/**
+ * ExecDelay class definition
+ */
+public class ExecDelay {
+  private final long _duration;
+  private final float _jitter;
+
+  private final long _delayBase;
+  private final long _delayRange;
+  private final Random _random;
+
+  public ExecDelay(long duration, float jitter) {
+    if (jitter < 0 || jitter > 1 || duration < 0) {
+      throw new IllegalArgumentException(
+          String.format("Invalid _jitter (%s) or _duration (%s)", jitter, duration));
+    }
+    _duration = duration;
+    _jitter = jitter;
+    _delayRange = Math.round(_duration * _jitter * 2);
+    _delayBase = _duration - _delayRange / 2;
+    _random = new Random();
+  }
+
+  /**
+   * Calculate the next delay based on the configured _duration and _jitter.
+   * @return The next delay in milliseconds.
+   */
+  public long getNextDelay() {
+    long randomDelay = _delayBase + _random.nextLong() % _delayRange;
+    return Math.max(randomDelay, 0);
+  }
+
+  public long getDuration() {
+    return _duration;
+  }
+
+  public float getJitter() {
+    return _jitter;
+  }
+}
diff --git a/meta-client/src/test/java/org/apache/helix/metaclient/puppy/PuppyManager.java b/meta-client/src/test/java/org/apache/helix/metaclient/puppy/PuppyManager.java
new file mode 100644
index 000000000..9ef948c59
--- /dev/null
+++ b/meta-client/src/test/java/org/apache/helix/metaclient/puppy/PuppyManager.java
@@ -0,0 +1,64 @@
+package org.apache.helix.metaclient.puppy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This class is used to manage the lifecycle of a set of _puppies.
+ */
+public class PuppyManager {
+  private final List<AbstractPuppy> _puppies = new ArrayList<>();
+  private final ExecutorService EXECUTOR_SERVICE = Executors.newCachedThreadPool();
+
+  public PuppyManager() {
+  }
+
+  public void addPuppy(AbstractPuppy puppy) {
+    _puppies.add(puppy);
+  }
+
+  public List<AbstractPuppy> getPuppies() {
+    return _puppies;
+  }
+
+  public void start(long timeoutInSeconds) {
+    for (AbstractPuppy puppy : _puppies) {
+      EXECUTOR_SERVICE.submit(puppy);
+    }
+
+    try {
+      EXECUTOR_SERVICE.awaitTermination(timeoutInSeconds, TimeUnit.SECONDS);
+    } catch (InterruptedException e) {
+      // Ignore
+    }
+
+    stop();
+  }
+
+  public void stop() {
+    EXECUTOR_SERVICE.shutdownNow();
+  }
+}
+
diff --git a/meta-client/src/test/java/org/apache/helix/metaclient/puppy/PuppyMode.java b/meta-client/src/test/java/org/apache/helix/metaclient/puppy/PuppyMode.java
new file mode 100644
index 000000000..d834f020e
--- /dev/null
+++ b/meta-client/src/test/java/org/apache/helix/metaclient/puppy/PuppyMode.java
@@ -0,0 +1,28 @@
+package org.apache.helix.metaclient.puppy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Enum for Puppy mode (OneOff or Repeat)
+ */
+public enum PuppyMode {
+  ONE_OFF,
+  REPEAT
+}
diff --git a/meta-client/src/test/java/org/apache/helix/metaclient/puppy/PuppySpec.java b/meta-client/src/test/java/org/apache/helix/metaclient/puppy/PuppySpec.java
new file mode 100644
index 000000000..ac6d527df
--- /dev/null
+++ b/meta-client/src/test/java/org/apache/helix/metaclient/puppy/PuppySpec.java
@@ -0,0 +1,53 @@
+package org.apache.helix.metaclient.puppy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * PuppySpec class definition
+ */
+public class PuppySpec {
+  private final PuppyMode _mode;
+  private final float _errorRate;
+  private final ExecDelay _execDelay;
+  private final int _numberDiffPaths;
+
+  public PuppySpec(PuppyMode mode, float errorRate, ExecDelay execDelay, int numberDiffPaths) {
+    _mode = mode;
+    _errorRate = errorRate;
+    _execDelay = execDelay;
+    _numberDiffPaths = numberDiffPaths;
+  }
+
+  public PuppyMode getMode() {
+    return _mode;
+  }
+
+  public float getErrorRate() {
+    return _errorRate;
+  }
+
+  public ExecDelay getExecDelay() {
+    return _execDelay;
+  }
+
+  public int getNumberDiffPaths() {
+    return _numberDiffPaths;
+  }
+}