Phased recovery
- Implemented a set of CLI commands
- Enable/disable group of ports
- List recovery phase of each device
- Force a specific device to enter given phase
- Return CompletableFuture in RRP
- Introduce completeAfter method in Tools
- Introduce submit method in PredictableExecutor which returns a CompletableFuture
Change-Id: I60b0fb7b67e392b33b52d908d2b53f7acbddc565
diff --git a/utils/misc/src/main/java/org/onlab/util/PredictableExecutor.java b/utils/misc/src/main/java/org/onlab/util/PredictableExecutor.java
index 279091c..b18a2fb 100644
--- a/utils/misc/src/main/java/org/onlab/util/PredictableExecutor.java
+++ b/utils/misc/src/main/java/org/onlab/util/PredictableExecutor.java
@@ -28,6 +28,7 @@
import java.util.Objects;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
@@ -136,6 +137,35 @@
execute(command, hintFunction.apply(command));
}
+ /**
+ * Submits a value-returning task for execution and returns a
+ * Future representing the pending results of the task. The
+ * Future's {@code get} method will return the task's result upon
+ * successful completion.
+ *
+ * @param command the {@link Runnable} task
+ * @param hint value to pick thread to run on.
+ * @return completable future representing the pending results
+ */
+ public CompletableFuture<Void> submit(Runnable command, int hint) {
+ int index = Math.abs(hint) % backends.size();
+ return CompletableFuture.runAsync(command, backends.get(index));
+ }
+
+ /**
+ * Submits a value-returning task for execution and returns a
+ * Future representing the pending results of the task. The
+ * Future's {@code get} method will return the task's result upon
+ * successful completion.
+ *
+ * @param command the {@link Runnable} task
+ * @param hintFunction Function to compute hint value
+ * @return completable future representing the pending results
+ */
+ public CompletableFuture<Void> submit(Runnable command, Function<Runnable, Integer> hintFunction) {
+ int hint = hintFunction.apply(command);
+ return submit(command, hint);
+ }
private static int hint(Runnable command) {
if (command instanceof PickyTask) {
diff --git a/utils/misc/src/main/java/org/onlab/util/Tools.java b/utils/misc/src/main/java/org/onlab/util/Tools.java
index e0ea0d5..596e34b 100644
--- a/utils/misc/src/main/java/org/onlab/util/Tools.java
+++ b/utils/misc/src/main/java/org/onlab/util/Tools.java
@@ -49,7 +49,9 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -80,6 +82,9 @@
private static final String INPUT_JSON_CANNOT_BE_NULL = "Input JSON cannot be null";
+ private static ScheduledExecutorService timer = Executors.newScheduledThreadPool(
+ Runtime.getRuntime().availableProcessors(), groupedThreads("onos/tool", "timer"));
+
/**
* Returns a thread factory that produces threads named according to the
* supplied name pattern.
@@ -699,6 +704,19 @@
}
/**
+ * Returns a future that completes normally after given time period.
+ *
+ * @param timeout amount of time to wait before completing the future
+ * @param unit Time unit
+ * @return a future that completes after given time period
+ */
+ public static CompletableFuture<Void> completeAfter(long timeout, TimeUnit unit) {
+ CompletableFuture<Void> result = new CompletableFuture<>();
+ timer.schedule(() -> result.complete(null), timeout, unit);
+ return result;
+ }
+
+ /**
* Returns a future that's completed using the given {@code orderedExecutor} if the future is not blocked or the
* given {@code threadPoolExecutor} if the future is blocked.
* <p>