From d706e38d8af22cbaf43104b5b53b3b40eaded81f Mon Sep 17 00:00:00 2001 From: Jerry Lee Date: Sat, 22 Jun 2024 19:36:29 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20reorder=20`tupleM*`=20methods=20?= =?UTF-8?q?=F0=9F=9A=9E=20=20and=20add=20related=20sections=20=F0=9F=92=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/foldright/cffu/CffuFactory.java | 293 +++---- .../cffu/CompletableFutureUtils.java | 776 +++++++++--------- .../io/foldright/cffu/CffuFactoryTest.java | 36 +- .../cffu/CompletableFutureUtilsTest.java | 36 +- 4 files changed, 578 insertions(+), 563 deletions(-) diff --git a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java index 94e6c3f6..e181c5a3 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java @@ -148,6 +148,135 @@ public Cffu runAsync(Runnable action, Executor executor) { return create(CompletableFuture.runAsync(action, executor)); } + // endregion + //////////////////////////////////////////////////////////// + // region## Multi-Actions(M*) Methods(create by actions) + //////////////////////////////////////////////////////////// + + /** + * Returns a new Cffu that is asynchronously completed + * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers + * in the same order of the given Suppliers arguments. + *

+ * This method is the same as {@link #tupleMSupplyAsync(Supplier, Supplier)} except for the fast-fail behavior. + * + * @return the new Cffu + * @see #allResultsOfFastFail(CompletionStage[]) + */ + @Contract(pure = true) + public Cffu> tupleMSupplyFastFailAsync( + Supplier supplier1, Supplier supplier2) { + return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(supplier1, supplier2)); + } + + /** + * Returns a new Cffu that is asynchronously completed + * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers + * in the same order of the given Suppliers arguments. + *

+ * This method is the same as {@link #tupleMSupplyAsync(Supplier, Supplier, Supplier)} except for the fast-fail behavior. + * + * @return the new Cffu + * @see #allResultsOfFastFail(CompletionStage[]) + */ + @Contract(pure = true) + public Cffu> tupleMSupplyFastFailAsync( + Supplier supplier1, Supplier supplier2, Supplier supplier3) { + return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(supplier1, supplier2, supplier3)); + } + + /** + * Returns a new Cffu that is asynchronously completed + * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers + * in the same order of the given Suppliers arguments. + *

+ * This method is the same as {@link #tupleMSupplyAsync(Supplier, Supplier, Supplier, Supplier)} except for the fast-fail behavior. + * + * @return the new Cffu + * @see #allResultsOfFastFail(CompletionStage[]) + */ + @Contract(pure = true) + public Cffu> tupleMSupplyFastFailAsync( + Supplier supplier1, Supplier supplier2, + Supplier supplier3, Supplier supplier4) { + return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(supplier1, supplier2, supplier3, supplier4)); + } + + /** + * Returns a new Cffu that is asynchronously completed + * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers + * in the same order of the given Suppliers arguments. + *

+ * This method is the same as {@link #tupleMSupplyAsync(Supplier, Supplier, Supplier, Supplier, Supplier)} except for the fast-fail behavior. + * + * @return the new Cffu + * @see #allResultsOfFastFail(CompletionStage[]) + */ + @Contract(pure = true) + public Cffu> tupleMSupplyFastFailAsync( + Supplier supplier1, Supplier supplier2, Supplier supplier3, + Supplier supplier4, Supplier supplier5) { + return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(supplier1, supplier2, supplier3, supplier4, supplier5)); + } + + /** + * Returns a new Cffu that is asynchronously completed + * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers + * in the same order of the given Suppliers arguments. + * + * @return the new Cffu + * @see #allResultsOf(CompletionStage[]) + */ + @Contract(pure = true) + public Cffu> tupleMSupplyAsync( + Supplier supplier1, Supplier supplier2) { + return create(CompletableFutureUtils.tupleMSupplyAsync(supplier1, supplier2)); + } + + /** + * Returns a new Cffu that is asynchronously completed + * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers + * in the same order of the given Suppliers arguments. + * + * @return the new Cffu + * @see #allResultsOf(CompletionStage[]) + */ + @Contract(pure = true) + public Cffu> tupleMSupplyAsync( + Supplier supplier1, Supplier supplier2, Supplier supplier3) { + return create(CompletableFutureUtils.tupleMSupplyAsync(supplier1, supplier2, supplier3)); + } + + /** + * Returns a new Cffu that is asynchronously completed + * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers + * in the same order of the given Suppliers arguments. + * + * @return the new Cffu + * @see #allResultsOf(CompletionStage[]) + */ + @Contract(pure = true) + public Cffu> tupleMSupplyAsync( + Supplier supplier1, Supplier supplier2, + Supplier supplier3, Supplier supplier4) { + return create(CompletableFutureUtils.tupleMSupplyAsync(supplier1, supplier2, supplier3, supplier4)); + } + + /** + * Returns a new Cffu that is asynchronously completed + * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers + * in the same order of the given Suppliers arguments. + * + * @return the new Cffu + * @see #allResultsOf(CompletionStage[]) + */ + @Contract(pure = true) + public Cffu> tupleMSupplyAsync( + Supplier supplier1, Supplier supplier2, Supplier supplier3, + Supplier supplier4, Supplier supplier5) { + return create(CompletableFutureUtils.tupleMSupplyAsync(supplier1, supplier2, supplier3, supplier4, supplier5)); + } + // endregion //////////////////////////////////////////////////////////////////////////////// // region## allOf* Methods(including mostResultsOfSuccess) @@ -547,130 +676,6 @@ public Cffu> mostTupleOfSuccess( return create(CompletableFutureUtils.mostTupleOfSuccess(defaultExecutor, timeout, unit, cf1, cf2, cf3, cf4, cf5)); } - /** - * Returns a new Cffu that is asynchronously completed - * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers - * in the same order of the given Suppliers arguments. - *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Supplier, Supplier)} except for the fast-fail behavior. - * - * @return the new Cffu - * @see #allResultsOfFastFail(CompletionStage[]) - */ - @Contract(pure = true) - public Cffu> allTupleOfMSupplyFastFailAsync( - Supplier supplier1, Supplier supplier2) { - return create(CompletableFutureUtils.allTupleOfMSupplyFastFailAsync(supplier1, supplier2)); - } - - /** - * Returns a new Cffu that is asynchronously completed - * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers - * in the same order of the given Suppliers arguments. - * - * @return the new Cffu - * @see #allResultsOf(CompletionStage[]) - */ - @Contract(pure = true) - public Cffu> allTupleOfMSupplyAsync( - Supplier supplier1, Supplier supplier2) { - return create(CompletableFutureUtils.allTupleOfMSupplyAsync(supplier1, supplier2)); - } - - /** - * Returns a new Cffu that is asynchronously completed - * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers - * in the same order of the given Suppliers arguments. - *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Supplier, Supplier, Supplier)} except for the fast-fail behavior. - * - * @return the new Cffu - * @see #allResultsOfFastFail(CompletionStage[]) - */ - @Contract(pure = true) - public Cffu> allTupleOfMSupplyFastFailAsync( - Supplier supplier1, Supplier supplier2, Supplier supplier3) { - return create(CompletableFutureUtils.allTupleOfMSupplyFastFailAsync(supplier1, supplier2, supplier3)); - } - - /** - * Returns a new Cffu that is asynchronously completed - * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers - * in the same order of the given Suppliers arguments. - * - * @return the new Cffu - * @see #allResultsOf(CompletionStage[]) - */ - @Contract(pure = true) - public Cffu> allTupleOfMSupplyAsync( - Supplier supplier1, Supplier supplier2, Supplier supplier3) { - return create(CompletableFutureUtils.allTupleOfMSupplyAsync(supplier1, supplier2, supplier3)); - } - - /** - * Returns a new Cffu that is asynchronously completed - * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers - * in the same order of the given Suppliers arguments. - *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Supplier, Supplier, Supplier, Supplier)} except for the fast-fail behavior. - * - * @return the new Cffu - * @see #allResultsOfFastFail(CompletionStage[]) - */ - @Contract(pure = true) - public Cffu> allTupleOfMSupplyFastFailAsync( - Supplier supplier1, Supplier supplier2, - Supplier supplier3, Supplier supplier4) { - return create(CompletableFutureUtils.allTupleOfMSupplyFastFailAsync(supplier1, supplier2, supplier3, supplier4)); - } - - /** - * Returns a new Cffu that is asynchronously completed - * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers - * in the same order of the given Suppliers arguments. - * - * @return the new Cffu - * @see #allResultsOf(CompletionStage[]) - */ - @Contract(pure = true) - public Cffu> allTupleOfMSupplyAsync( - Supplier supplier1, Supplier supplier2, - Supplier supplier3, Supplier supplier4) { - return create(CompletableFutureUtils.allTupleOfMSupplyAsync(supplier1, supplier2, supplier3, supplier4)); - } - - /** - * Returns a new Cffu that is asynchronously completed - * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers - * in the same order of the given Suppliers arguments. - *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Supplier, Supplier, Supplier, Supplier, Supplier)} except for the fast-fail behavior. - * - * @return the new Cffu - * @see #allResultsOfFastFail(CompletionStage[]) - */ - @Contract(pure = true) - public Cffu> allTupleOfMSupplyFastFailAsync( - Supplier supplier1, Supplier supplier2, Supplier supplier3, - Supplier supplier4, Supplier supplier5) { - return create(CompletableFutureUtils.allTupleOfMSupplyFastFailAsync(supplier1, supplier2, supplier3, supplier4, supplier5)); - } - - /** - * Returns a new Cffu that is asynchronously completed - * by tasks running in the {@link #defaultExecutor()} with the values obtained by calling the given Suppliers - * in the same order of the given Suppliers arguments. - * - * @return the new Cffu - * @see #allResultsOf(CompletionStage[]) - */ - @Contract(pure = true) - public Cffu> allTupleOfMSupplyAsync( - Supplier supplier1, Supplier supplier2, Supplier supplier3, - Supplier supplier4, Supplier supplier5) { - return create(CompletableFutureUtils.allTupleOfMSupplyAsync(supplier1, supplier2, supplier3, supplier4, supplier5)); - } - /** * Returns a new Cffu that, when the given stage completes normally, * is executed using the {@link #defaultExecutor()}, @@ -678,15 +683,15 @@ public Cffu> allTupleOfMSupplyAs * (with the given stage's result as the argument to the given functions) * in the same order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Function, Function)} * except for the fast-fail behavior. * * @return the new Cffu */ @Contract(pure = true) - public Cffu> allTupleOfThenMApplyFastFailAsync( + public Cffu> thenTupleMApplyFastFailAsync( CompletionStage cf, Function fn1, Function fn2) { - return create(CompletableFutureUtils.allTupleOfThenMApplyFastFailAsync(cf, fn1, fn2)); + return create(CompletableFutureUtils.thenTupleMApplyFastFailAsync(cf, fn1, fn2)); } /** @@ -696,16 +701,16 @@ public Cffu> allTupleOfThenMApplyFastFailAsync( * (with the given stage's result as the argument to the given functions) * in the same order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Function, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Function, Function, Function)} * except for the fast-fail behavior. * * @return the new Cffu */ @Contract(pure = true) - public Cffu> allTupleOfThenMApplyFastFailAsync( + public Cffu> thenTupleMApplyFastFailAsync( CompletionStage cf, Function fn1, Function fn2, Function fn3) { - return create(CompletableFutureUtils.allTupleOfThenMApplyFastFailAsync(cf, fn1, fn2, fn3)); + return create(CompletableFutureUtils.thenTupleMApplyFastFailAsync(cf, fn1, fn2, fn3)); } /** @@ -715,17 +720,17 @@ public Cffu> allTupleOfThenMApplyFastFailAsyn * (with the given stage's result as the argument to the given functions) * in the same order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Function, Function, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Function, Function, Function, Function)} * except for the fast-fail behavior. * * @return the new Cffu */ @Contract(pure = true) - public Cffu> allTupleOfThenMApplyFastFailAsync( + public Cffu> thenTupleMApplyFastFailAsync( CompletionStage cf, Function fn1, Function fn2, Function fn3, Function fn4) { - return create(CompletableFutureUtils.allTupleOfThenMApplyFastFailAsync(cf, fn1, fn2, fn3, fn4)); + return create(CompletableFutureUtils.thenTupleMApplyFastFailAsync(cf, fn1, fn2, fn3, fn4)); } /** @@ -735,17 +740,17 @@ public Cffu> allTupleOfThenMApplyFast * (with the given stage's result as the argument to the given functions) * in the same order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Function, Function, Function, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Function, Function, Function, Function, Function)} * except for the fast-fail behavior. * * @return the new Cffu */ @Contract(pure = true) - public Cffu> allTupleOfThenMApplyFastFailAsync( + public Cffu> thenTupleMApplyFastFailAsync( CompletionStage cf, Function fn1, Function fn2, Function fn3, Function fn4, Function fn5) { - return create(CompletableFutureUtils.allTupleOfThenMApplyFastFailAsync(cf, fn1, fn2, fn3, fn4, fn5)); + return create(CompletableFutureUtils.thenTupleMApplyFastFailAsync(cf, fn1, fn2, fn3, fn4, fn5)); } /** @@ -758,10 +763,10 @@ public Cffu> allTupleOfThenMA * @return the new Cffu */ @Contract(pure = true) - public Cffu> allTupleOfThenMApplyAsync( + public Cffu> thenTupleMApplyAsync( CompletionStage cf, Function fn1, Function fn2) { - return create(CompletableFutureUtils.allTupleOfThenMApplyAsync(cf, fn1, fn2)); + return create(CompletableFutureUtils.thenTupleMApplyAsync(cf, fn1, fn2)); } /** @@ -774,10 +779,10 @@ public Cffu> allTupleOfThenMApplyAsync( * @return the new Cffu */ @Contract(pure = true) - public Cffu> allTupleOfThenMApplyAsync( + public Cffu> thenTupleMApplyAsync( CompletionStage cf, Function fn1, Function fn2, Function fn3) { - return create(CompletableFutureUtils.allTupleOfThenMApplyAsync(cf, fn1, fn2, fn3)); + return create(CompletableFutureUtils.thenTupleMApplyAsync(cf, fn1, fn2, fn3)); } /** @@ -790,11 +795,11 @@ public Cffu> allTupleOfThenMApplyAsync( * @return the new Cffu */ @Contract(pure = true) - public Cffu> allTupleOfThenMApplyAsync( + public Cffu> thenTupleMApplyAsync( CompletionStage cf, Function fn1, Function fn2, Function fn3, Function fn4) { - return create(CompletableFutureUtils.allTupleOfThenMApplyAsync(cf, fn1, fn2, fn3, fn4)); + return create(CompletableFutureUtils.thenTupleMApplyAsync(cf, fn1, fn2, fn3, fn4)); } /** @@ -807,11 +812,11 @@ public Cffu> allTupleOfThenMApplyAsyn * @return the new Cffu */ @Contract(pure = true) - public Cffu> allTupleOfThenMApplyAsync( + public Cffu> thenTupleMApplyAsync( CompletionStage cf, Function fn1, Function fn2, Function fn3, Function fn4, Function fn5) { - return create(CompletableFutureUtils.allTupleOfThenMApplyAsync(cf, fn1, fn2, fn3, fn4, fn5)); + return create(CompletableFutureUtils.thenTupleMApplyAsync(cf, fn1, fn2, fn3, fn4, fn5)); } // endregion diff --git a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java index e14ffff9..33f5d403 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -80,38 +80,56 @@ public static CompletableFuture> mSupplyFastFailAsync( /** * Returns a new CompletableFuture that is asynchronously completed * by tasks running in the CompletableFuture's default asynchronous execution facility - * with the values obtained by calling the given Suppliers + * with the most values obtained by calling the given Suppliers + * in the given time({@code timeout}, aka as many results as possible in the given time) * in the same order of the given Suppliers arguments. *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Supplier, Supplier)} except for the fast-fail behavior. + * If the given supplier is successful in the given time, the return result is the completed value; + * Otherwise the given valueIfNotSuccess. * + * @param valueIfNotSuccess the value to return if not completed successfully + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @param suppliers the suppliers returning the value to be used to complete the returned CompletableFuture + * @param the suppliers' return type * @return the new CompletableFuture - * @see #allResultsOfFastFail(CompletionStage[]) + * @see #mostResultsOfSuccess(Object, long, TimeUnit, CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyFastFailAsync( - Supplier supplier1, Supplier supplier2) { - return allTupleOfMSupplyFastFailAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2); + @SafeVarargs + public static CompletableFuture> mSupplyMostSuccessAsync( + @Nullable T valueIfNotSuccess, long timeout, TimeUnit unit, Supplier... suppliers) { + return mSupplyMostSuccessAsync(valueIfNotSuccess, AsyncPoolHolder.ASYNC_POOL, timeout, unit, suppliers); } /** * Returns a new CompletableFuture that is asynchronously completed - * by tasks running in the given Executor with the values obtained by calling the given Suppliers + * by tasks running in the given Executor with the most values obtained by calling the given Suppliers + * in the given time({@code timeout}, aka as many results as possible in the given time) * in the same order of the given Suppliers arguments. *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Executor, Supplier, Supplier)} except for the fast-fail behavior. + * If the given supplier is successful in the given time, the return result is the completed value; + * Otherwise the given valueIfNotSuccess. * - * @param executor the executor to use for asynchronous execution + * @param valueIfNotSuccess the value to return if not completed successfully + * @param executor the executor to use for asynchronous execution + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @param suppliers the suppliers returning the value to be used to complete the returned CompletableFuture + * @param the suppliers' return type * @return the new CompletableFuture - * @see #allResultsOfFastFail(CompletionStage[]) + * @see #mostResultsOfSuccess(Object, Executor, long, TimeUnit, CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier, Executor) */ - public static CompletableFuture> allTupleOfMSupplyFastFailAsync( - Executor executor, Supplier supplier1, Supplier supplier2) { + @SafeVarargs + public static CompletableFuture> mSupplyMostSuccessAsync( + @Nullable T valueIfNotSuccess, Executor executor, long timeout, TimeUnit unit, + Supplier... suppliers) { requireNonNull(executor, "executor is null"); - Supplier[] suppliers = requireArrayAndEleNonNull("supplier", supplier1, supplier2); + requireNonNull(unit, "unit is null"); + requireArrayAndEleNonNull("supplier", suppliers); - return allTupleOf0(wrapSuppliers(executor, suppliers), true); + return mostResultsOfSuccess(valueIfNotSuccess, executor, timeout, unit, wrapSuppliers(executor, suppliers)); } /** @@ -119,58 +137,152 @@ public static CompletableFuture> allTupleOfMSupplyFastFa * by tasks running in the CompletableFuture's default asynchronous execution facility * with the values obtained by calling the given Suppliers * in the same order of the given Suppliers arguments. - *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Supplier, Supplier, Supplier)} - * except for the fast-fail behavior. * + * @param suppliers the suppliers returning the value to be used to complete the returned CompletableFuture + * @param the suppliers' return type * @return the new CompletableFuture - * @see #allResultsOfFastFail(CompletionStage[]) + * @see #allResultsOf(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyFastFailAsync( - Supplier supplier1, Supplier supplier2, Supplier supplier3) { - return allTupleOfMSupplyFastFailAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3); + @SafeVarargs + public static CompletableFuture> mSupplyAsync(Supplier... suppliers) { + return mSupplyAsync(AsyncPoolHolder.ASYNC_POOL, suppliers); } /** * Returns a new CompletableFuture that is asynchronously completed * by tasks running in the given Executor with the values obtained by calling the given Suppliers * in the same order of the given Suppliers arguments. + * + * @param executor the executor to use for asynchronous execution + * @param suppliers the suppliers returning the value to be used to complete the returned CompletableFuture + * @param the suppliers' return type + * @return the new CompletableFuture + * @see #allResultsOf(CompletionStage[]) + * @see CompletableFuture#supplyAsync(Supplier, Executor) + */ + @SafeVarargs + public static CompletableFuture> mSupplyAsync(Executor executor, Supplier... suppliers) { + requireNonNull(executor, "executor is null"); + requireArrayAndEleNonNull("supplier", suppliers); + + return allResultsOf(wrapSuppliers(executor, suppliers)); + } + + @SafeVarargs + private static T[] requireArrayAndEleNonNull(String varName, T... array) { + requireNonNull(array, varName + "s is null"); + for (int i = 0; i < array.length; i++) { + requireNonNull(array[i], varName + (i + 1) + " is null"); + } + return array; + } + + private static CompletableFuture[] wrapSuppliers( + Executor executor, Supplier[] suppliers) { + @SuppressWarnings("unchecked") + CompletableFuture[] cfs = new CompletableFuture[suppliers.length]; + for (int i = 0; i < suppliers.length; i++) { + cfs[i] = CompletableFuture.supplyAsync(suppliers[i], executor); + } + return cfs; + } + + /** + * Returns a new CompletableFuture that is asynchronously completed + * by tasks running in the CompletableFuture's default asynchronous execution facility + * after runs the given actions. + * + * @param actions the actions to run before completing the returned CompletableFuture + * @return the new CompletableFuture + * @see #allOf(CompletionStage[]) + * @see CompletableFuture#runAsync(Runnable) + */ + public static CompletableFuture mRunAsync(Runnable... actions) { + return mRunAsync(AsyncPoolHolder.ASYNC_POOL, actions); + } + + /** + * Returns a new CompletableFuture that is asynchronously completed + * by tasks running in the given Executor after runs the given actions. + * + * @param executor the executor to use for asynchronous execution + * @param actions the actions to run before completing the returned CompletableFuture + * @return the new CompletableFuture + * @see #allOf(CompletionStage[]) + * @see CompletableFuture#runAsync(Runnable, Executor) + */ + public static CompletableFuture mRunAsync(Executor executor, Runnable... actions) { + requireNonNull(executor, "executor is null"); + requireArrayAndEleNonNull("action", actions); + + return CompletableFuture.allOf(wrapActions(executor, actions)); + } + + /** + * Returns a new CompletableFuture that is asynchronously completed + * by tasks running in the CompletableFuture's default asynchronous execution facility + * after runs the given actions. *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Executor, Supplier, Supplier, Supplier)} - * except for the fast-fail behavior. + * This method is the same as {@link #mRunAsync(Runnable...)} except for the fast-fail behavior. + * + * @param actions the actions to run before completing the returned CompletableFuture + * @return the new CompletableFuture + * @see #allOfFastFail(CompletionStage[]) + * @see CompletableFuture#runAsync(Runnable) + */ + public static CompletableFuture mRunFastFailAsync(Runnable... actions) { + return mRunFastFailAsync(AsyncPoolHolder.ASYNC_POOL, actions); + } + + /** + * Returns a new CompletableFuture that is asynchronously completed + * by tasks running in the given Executor after runs the given actions. + *

+ * This method is the same as {@link #mRunAsync(Executor, Runnable...)} except for the fast-fail behavior. * * @param executor the executor to use for asynchronous execution + * @param actions the actions to run before completing the returned CompletableFuture * @return the new CompletableFuture - * @see #allResultsOfFastFail(CompletionStage[]) - * @see CompletableFuture#supplyAsync(Supplier, Executor) + * @see #allOfFastFail(CompletionStage[]) + * @see CompletableFuture#runAsync(Runnable, Executor) */ - public static CompletableFuture> allTupleOfMSupplyFastFailAsync( - Executor executor, - Supplier supplier1, Supplier supplier2, Supplier supplier3) { + public static CompletableFuture mRunFastFailAsync(Executor executor, Runnable... actions) { requireNonNull(executor, "executor is null"); - Supplier[] suppliers = requireArrayAndEleNonNull("supplier", supplier1, supplier2, supplier3); + requireArrayAndEleNonNull("action", actions); - return allTupleOf0(wrapSuppliers(executor, suppliers), true); + return allOfFastFail(wrapActions(executor, actions)); + } + + private static CompletableFuture[] wrapActions(Executor executor, Runnable[] actions) { + @SuppressWarnings("unchecked") + CompletableFuture[] cfs = new CompletableFuture[actions.length]; + for (int i = 0; i < actions.length; i++) { + cfs[i] = CompletableFuture.runAsync(actions[i], executor); + } + return cfs; } + // endregion + //////////////////////////////////////////////////////////// + // region## Tuple-Multi-Actions(tupleM*) Methods(create by actions) + //////////////////////////////////////////////////////////// + /** * Returns a new CompletableFuture that is asynchronously completed * by tasks running in the CompletableFuture's default asynchronous execution facility * with the values obtained by calling the given Suppliers * in the same order of the given Suppliers arguments. *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Supplier, Supplier, Supplier, Supplier)} - * except for the fast-fail behavior. + * This method is the same as {@link #tupleMSupplyAsync(Supplier, Supplier)} except for the fast-fail behavior. * * @return the new CompletableFuture * @see #allResultsOfFastFail(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyFastFailAsync( - Supplier supplier1, Supplier supplier2, - Supplier supplier3, Supplier supplier4) { - return allTupleOfMSupplyFastFailAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3, supplier4); + public static CompletableFuture> tupleMSupplyFastFailAsync( + Supplier supplier1, Supplier supplier2) { + return tupleMSupplyFastFailAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2); } /** @@ -178,19 +290,17 @@ public static CompletableFuture> allTupl * by tasks running in the given Executor with the values obtained by calling the given Suppliers * in the same order of the given Suppliers arguments. *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Executor, Supplier, Supplier, Supplier, Supplier)} - * except for the fast-fail behavior. + * This method is the same as {@link #tupleMSupplyAsync(Executor, Supplier, Supplier)} except for the fast-fail behavior. * * @param executor the executor to use for asynchronous execution * @return the new CompletableFuture * @see #allResultsOfFastFail(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier, Executor) */ - public static CompletableFuture> allTupleOfMSupplyFastFailAsync( - Executor executor, Supplier supplier1, Supplier supplier2, - Supplier supplier3, Supplier supplier4) { + public static CompletableFuture> tupleMSupplyFastFailAsync( + Executor executor, Supplier supplier1, Supplier supplier2) { requireNonNull(executor, "executor is null"); - Supplier[] suppliers = requireArrayAndEleNonNull("supplier", supplier1, supplier2, supplier3, supplier4); + Supplier[] suppliers = requireArrayAndEleNonNull("supplier", supplier1, supplier2); return allTupleOf0(wrapSuppliers(executor, suppliers), true); } @@ -201,17 +311,16 @@ public static CompletableFuture> allTupl * with the values obtained by calling the given Suppliers * in the same order of the given Suppliers arguments. *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Supplier, Supplier, Supplier, Supplier, Supplier)} + * This method is the same as {@link #tupleMSupplyAsync(Supplier, Supplier, Supplier)} * except for the fast-fail behavior. * * @return the new CompletableFuture * @see #allResultsOfFastFail(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyFastFailAsync( - Supplier supplier1, Supplier supplier2, - Supplier supplier3, Supplier supplier4, Supplier supplier5) { - return allTupleOfMSupplyFastFailAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3, supplier4, supplier5); + public static CompletableFuture> tupleMSupplyFastFailAsync( + Supplier supplier1, Supplier supplier2, Supplier supplier3) { + return tupleMSupplyFastFailAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3); } /** @@ -219,7 +328,7 @@ public static CompletableFuture> * by tasks running in the given Executor with the values obtained by calling the given Suppliers * in the same order of the given Suppliers arguments. *

- * This method is the same as {@link #allTupleOfMSupplyAsync(Supplier, Supplier, Supplier, Supplier, Supplier)} + * This method is the same as {@link #tupleMSupplyAsync(Executor, Supplier, Supplier, Supplier)} * except for the fast-fail behavior. * * @param executor the executor to use for asynchronous execution @@ -227,11 +336,11 @@ public static CompletableFuture> * @see #allResultsOfFastFail(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier, Executor) */ - public static CompletableFuture> allTupleOfMSupplyFastFailAsync( - Executor executor, Supplier supplier1, Supplier supplier2, - Supplier supplier3, Supplier supplier4, Supplier supplier5) { + public static CompletableFuture> tupleMSupplyFastFailAsync( + Executor executor, + Supplier supplier1, Supplier supplier2, Supplier supplier3) { requireNonNull(executor, "executor is null"); - Supplier[] suppliers = requireArrayAndEleNonNull("supplier", supplier1, supplier2, supplier3, supplier4, supplier5); + Supplier[] suppliers = requireArrayAndEleNonNull("supplier", supplier1, supplier2, supplier3); return allTupleOf0(wrapSuppliers(executor, suppliers), true); } @@ -239,56 +348,42 @@ public static CompletableFuture> /** * Returns a new CompletableFuture that is asynchronously completed * by tasks running in the CompletableFuture's default asynchronous execution facility - * with the most values obtained by calling the given Suppliers - * in the given time({@code timeout}, aka as many results as possible in the given time) + * with the values obtained by calling the given Suppliers * in the same order of the given Suppliers arguments. *

- * If the given supplier is successful in the given time, the return result is the completed value; - * Otherwise the given valueIfNotSuccess. + * This method is the same as {@link #tupleMSupplyAsync(Supplier, Supplier, Supplier, Supplier)} + * except for the fast-fail behavior. * - * @param valueIfNotSuccess the value to return if not completed successfully - * @param timeout how long to wait in units of {@code unit} - * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter - * @param suppliers the suppliers returning the value to be used to complete the returned CompletableFuture - * @param the suppliers' return type * @return the new CompletableFuture - * @see #mostResultsOfSuccess(Object, long, TimeUnit, CompletionStage[]) + * @see #allResultsOfFastFail(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - @SafeVarargs - public static CompletableFuture> mSupplyMostSuccessAsync( - @Nullable T valueIfNotSuccess, long timeout, TimeUnit unit, Supplier... suppliers) { - return mSupplyMostSuccessAsync(valueIfNotSuccess, AsyncPoolHolder.ASYNC_POOL, timeout, unit, suppliers); + public static CompletableFuture> tupleMSupplyFastFailAsync( + Supplier supplier1, Supplier supplier2, + Supplier supplier3, Supplier supplier4) { + return tupleMSupplyFastFailAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3, supplier4); } /** * Returns a new CompletableFuture that is asynchronously completed - * by tasks running in the given Executor with the most values obtained by calling the given Suppliers - * in the given time({@code timeout}, aka as many results as possible in the given time) + * by tasks running in the given Executor with the values obtained by calling the given Suppliers * in the same order of the given Suppliers arguments. *

- * If the given supplier is successful in the given time, the return result is the completed value; - * Otherwise the given valueIfNotSuccess. + * This method is the same as {@link #tupleMSupplyAsync(Executor, Supplier, Supplier, Supplier, Supplier)} + * except for the fast-fail behavior. * - * @param valueIfNotSuccess the value to return if not completed successfully - * @param executor the executor to use for asynchronous execution - * @param timeout how long to wait in units of {@code unit} - * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter - * @param suppliers the suppliers returning the value to be used to complete the returned CompletableFuture - * @param the suppliers' return type + * @param executor the executor to use for asynchronous execution * @return the new CompletableFuture - * @see #mostResultsOfSuccess(Object, Executor, long, TimeUnit, CompletionStage[]) + * @see #allResultsOfFastFail(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier, Executor) */ - @SafeVarargs - public static CompletableFuture> mSupplyMostSuccessAsync( - @Nullable T valueIfNotSuccess, Executor executor, long timeout, TimeUnit unit, - Supplier... suppliers) { + public static CompletableFuture> tupleMSupplyFastFailAsync( + Executor executor, Supplier supplier1, Supplier supplier2, + Supplier supplier3, Supplier supplier4) { requireNonNull(executor, "executor is null"); - requireNonNull(unit, "unit is null"); - requireArrayAndEleNonNull("supplier", suppliers); + Supplier[] suppliers = requireArrayAndEleNonNull("supplier", supplier1, supplier2, supplier3, supplier4); - return mostResultsOfSuccess(valueIfNotSuccess, executor, timeout, unit, wrapSuppliers(executor, suppliers)); + return allTupleOf0(wrapSuppliers(executor, suppliers), true); } /** @@ -296,36 +391,40 @@ public static CompletableFuture> mSupplyMostSuccessAsync( * by tasks running in the CompletableFuture's default asynchronous execution facility * with the values obtained by calling the given Suppliers * in the same order of the given Suppliers arguments. + *

+ * This method is the same as {@link #tupleMSupplyAsync(Supplier, Supplier, Supplier, Supplier, Supplier)} + * except for the fast-fail behavior. * - * @param suppliers the suppliers returning the value to be used to complete the returned CompletableFuture - * @param the suppliers' return type * @return the new CompletableFuture - * @see #allResultsOf(CompletionStage[]) + * @see #allResultsOfFastFail(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - @SafeVarargs - public static CompletableFuture> mSupplyAsync(Supplier... suppliers) { - return mSupplyAsync(AsyncPoolHolder.ASYNC_POOL, suppliers); + public static CompletableFuture> tupleMSupplyFastFailAsync( + Supplier supplier1, Supplier supplier2, + Supplier supplier3, Supplier supplier4, Supplier supplier5) { + return tupleMSupplyFastFailAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3, supplier4, supplier5); } /** * Returns a new CompletableFuture that is asynchronously completed * by tasks running in the given Executor with the values obtained by calling the given Suppliers * in the same order of the given Suppliers arguments. + *

+ * This method is the same as {@link #tupleMSupplyAsync(Supplier, Supplier, Supplier, Supplier, Supplier)} + * except for the fast-fail behavior. * - * @param executor the executor to use for asynchronous execution - * @param suppliers the suppliers returning the value to be used to complete the returned CompletableFuture - * @param the suppliers' return type + * @param executor the executor to use for asynchronous execution * @return the new CompletableFuture - * @see #allResultsOf(CompletionStage[]) + * @see #allResultsOfFastFail(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier, Executor) */ - @SafeVarargs - public static CompletableFuture> mSupplyAsync(Executor executor, Supplier... suppliers) { + public static CompletableFuture> tupleMSupplyFastFailAsync( + Executor executor, Supplier supplier1, Supplier supplier2, + Supplier supplier3, Supplier supplier4, Supplier supplier5) { requireNonNull(executor, "executor is null"); - requireArrayAndEleNonNull("supplier", suppliers); + Supplier[] suppliers = requireArrayAndEleNonNull("supplier", supplier1, supplier2, supplier3, supplier4, supplier5); - return allResultsOf(wrapSuppliers(executor, suppliers)); + return allTupleOf0(wrapSuppliers(executor, suppliers), true); } /** @@ -338,9 +437,9 @@ public static CompletableFuture> mSupplyAsync(Executor executor, Sup * @see #allResultsOf(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyAsync( + public static CompletableFuture> tupleMSupplyAsync( Supplier supplier1, Supplier supplier2) { - return allTupleOfMSupplyAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2); + return tupleMSupplyAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2); } /** @@ -352,7 +451,7 @@ public static CompletableFuture> allTupleOfMSupplyAsync( * @see #allResultsOf(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyAsync( + public static CompletableFuture> tupleMSupplyAsync( Executor executor, Supplier supplier1, Supplier supplier2) { requireNonNull(executor, "executor is null"); Supplier[] suppliers = requireArrayAndEleNonNull("supplier", supplier1, supplier2); @@ -370,9 +469,9 @@ public static CompletableFuture> allTupleOfMSupplyAsync( * @see #allResultsOf(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyAsync( + public static CompletableFuture> tupleMSupplyAsync( Supplier supplier1, Supplier supplier2, Supplier supplier3) { - return allTupleOfMSupplyAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3); + return tupleMSupplyAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3); } /** @@ -384,7 +483,7 @@ public static CompletableFuture> allTupleOfMSupp * @see #allResultsOf(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyAsync( + public static CompletableFuture> tupleMSupplyAsync( Executor executor, Supplier supplier1, Supplier supplier2, Supplier supplier3) { requireNonNull(executor, "executor is null"); @@ -403,10 +502,10 @@ public static CompletableFuture> allTupleOfMSupp * @see #allResultsOf(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyAsync( + public static CompletableFuture> tupleMSupplyAsync( Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4) { - return allTupleOfMSupplyAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3, supplier4); + return tupleMSupplyAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3, supplier4); } /** @@ -418,7 +517,7 @@ public static CompletableFuture> allTupl * @see #allResultsOf(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyAsync( + public static CompletableFuture> tupleMSupplyAsync( Executor executor, Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4) { requireNonNull(executor, "executor is null"); @@ -437,10 +536,10 @@ public static CompletableFuture> allTupl * @see #allResultsOf(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyAsync( + public static CompletableFuture> tupleMSupplyAsync( Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4, Supplier supplier5) { - return allTupleOfMSupplyAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3, supplier4, supplier5); + return tupleMSupplyAsync(AsyncPoolHolder.ASYNC_POOL, supplier1, supplier2, supplier3, supplier4, supplier5); } /** @@ -452,7 +551,7 @@ public static CompletableFuture> * @see #allResultsOf(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public static CompletableFuture> allTupleOfMSupplyAsync( + public static CompletableFuture> tupleMSupplyAsync( Executor executor, Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4, Supplier supplier5) { requireNonNull(executor, "executor is null"); @@ -461,100 +560,6 @@ public static CompletableFuture> return allTupleOf0(wrapSuppliers(executor, suppliers), false); } - @SafeVarargs - private static T[] requireArrayAndEleNonNull(String varName, T... array) { - requireNonNull(array, varName + "s is null"); - for (int i = 0; i < array.length; i++) { - requireNonNull(array[i], varName + (i + 1) + " is null"); - } - return array; - } - - private static CompletableFuture[] wrapSuppliers( - Executor executor, Supplier[] suppliers) { - @SuppressWarnings("unchecked") - CompletableFuture[] cfs = new CompletableFuture[suppliers.length]; - for (int i = 0; i < suppliers.length; i++) { - cfs[i] = CompletableFuture.supplyAsync(suppliers[i], executor); - } - return cfs; - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * by tasks running in the CompletableFuture's default asynchronous execution facility - * after runs the given actions. - * - * @param actions the actions to run before completing the returned CompletableFuture - * @return the new CompletableFuture - * @see #allOf(CompletionStage[]) - * @see CompletableFuture#runAsync(Runnable) - */ - public static CompletableFuture mRunAsync(Runnable... actions) { - return mRunAsync(AsyncPoolHolder.ASYNC_POOL, actions); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * by tasks running in the given Executor after runs the given actions. - * - * @param executor the executor to use for asynchronous execution - * @param actions the actions to run before completing the returned CompletableFuture - * @return the new CompletableFuture - * @see #allOf(CompletionStage[]) - * @see CompletableFuture#runAsync(Runnable, Executor) - */ - public static CompletableFuture mRunAsync(Executor executor, Runnable... actions) { - requireNonNull(executor, "executor is null"); - requireArrayAndEleNonNull("action", actions); - - return CompletableFuture.allOf(wrapActions(executor, actions)); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * by tasks running in the CompletableFuture's default asynchronous execution facility - * after runs the given actions. - *

- * This method is the same as {@link #mRunAsync(Runnable...)} except for the fast-fail behavior. - * - * @param actions the actions to run before completing the returned CompletableFuture - * @return the new CompletableFuture - * @see #allOfFastFail(CompletionStage[]) - * @see CompletableFuture#runAsync(Runnable) - */ - public static CompletableFuture mRunFastFailAsync(Runnable... actions) { - return mRunFastFailAsync(AsyncPoolHolder.ASYNC_POOL, actions); - } - - /** - * Returns a new CompletableFuture that is asynchronously completed - * by tasks running in the given Executor after runs the given actions. - *

- * This method is the same as {@link #mRunAsync(Executor, Runnable...)} except for the fast-fail behavior. - * - * @param executor the executor to use for asynchronous execution - * @param actions the actions to run before completing the returned CompletableFuture - * @return the new CompletableFuture - * @see #allOfFastFail(CompletionStage[]) - * @see CompletableFuture#runAsync(Runnable, Executor) - */ - public static CompletableFuture mRunFastFailAsync(Executor executor, Runnable... actions) { - requireNonNull(executor, "executor is null"); - requireArrayAndEleNonNull("action", actions); - - return allOfFastFail(wrapActions(executor, actions)); - } - - private static CompletableFuture[] wrapActions(Executor executor, Runnable[] actions) { - @SuppressWarnings("unchecked") - CompletableFuture[] cfs = new CompletableFuture[actions.length]; - for (int i = 0; i < actions.length; i++) { - cfs[i] = CompletableFuture.runAsync(actions[i], executor); - } - return cfs; - } - // endregion //////////////////////////////////////////////////////////// // region## allOf* Methods(including mostResultsOfSuccess) @@ -1434,7 +1439,7 @@ public static Executor defaultExecutor() { //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// - // region## Then-Multi-Actions(M*) Methods + // region## Then-Multi-Actions(thenM*) Methods //////////////////////////////////////////////////////////// /** @@ -1573,142 +1578,167 @@ public static CompletableFuture> thenMApplyAsync( return toNonMinCf(cf).thenCompose(v -> allResultsOf(wrapFunctions(executor, v, fns))); } + private static CompletableFuture[] wrapFunctions( + Executor executor, @Nullable T v, Function[] fns) { + @SuppressWarnings("unchecked") + CompletableFuture[] cfs = new CompletableFuture[fns.length]; + for (int i = 0; i < fns.length; i++) { + final int idx = i; + cfs[i] = CompletableFuture.supplyAsync(() -> fns[idx].apply(v), executor); + } + return cfs; + } + /** * Returns a new CompletableFuture that, when the given stage completes normally, * is executed using the CompletableFuture's default asynchronous execution facility, - * with the values obtained by calling the given Functions - * (with the given stage's result as the argument to the given functions) - * in the same order of the given Functions arguments. + * with the given stage's result as the argument to the given actions. * + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyAsync( - CompletionStage cf, - Function fn1, Function fn2) { - return allTupleOfThenMApplyAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2); + @SafeVarargs + public static CompletableFuture thenMAcceptAsync( + CompletionStage cf, Consumer... actions) { + return thenMAcceptAsync(cf, AsyncPoolHolder.ASYNC_POOL, actions); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * is executed using the given Executor, with the values obtained by calling the given Functions - * (with the given stage's result as the argument to the given functions) - * in the same order of the given Functions arguments. + * is executed using the given Executor, with the given stage's result as the argument to the given actions. * + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyAsync( - CompletionStage cf, Executor executor, - Function fn1, Function fn2) { + @SafeVarargs + public static CompletableFuture thenMAcceptAsync( + CompletionStage cf, Executor executor, Consumer... actions) { requireNonNull(cf, "cf is null"); requireNonNull(executor, "executor is null"); - Function[] fns = requireArrayAndEleNonNull("fn", fn1, fn2); + requireArrayAndEleNonNull("action", actions); - return toNonMinCf(cf).thenCompose(v -> allTupleOf0(wrapFunctions(executor, null, fns), false)); + return toNonMinCf(cf).thenCompose(v -> CompletableFuture.allOf(wrapConsumers(executor, v, actions))); } /** * Returns a new CompletableFuture that, when the given stage completes normally, * is executed using the CompletableFuture's default asynchronous execution facility, - * with the values obtained by calling the given Functions - * (with the given stage's result as the argument to the given functions) - * in the same order of the given Functions arguments. + * with the given stage's result as the argument to the given actions. + *

+ * This method is the same as {@link #thenMAcceptAsync(CompletionStage, Consumer[])} + * except for the fast-fail behavior. * + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyAsync( - CompletionStage cf, Function fn1, - Function fn2, Function fn3) { - return allTupleOfThenMApplyAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3); + @SafeVarargs + public static CompletableFuture thenMAcceptFastFailAsync( + CompletionStage cf, Consumer... actions) { + return thenMAcceptFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, actions); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * is executed using the given Executor, with the values obtained by calling the given Functions - * (with the given stage's result as the argument to the given functions) - * in the same order of the given Functions arguments. + * is executed using the given Executor, with the given stage's result as the argument to the given actions. + *

+ * This method is the same as {@link #thenMAcceptAsync(CompletionStage, Executor, Consumer[])} + * except for the fast-fail behavior. * + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyAsync( - CompletionStage cf, Executor executor, Function fn1, - Function fn2, Function fn3) { + @SafeVarargs + public static CompletableFuture thenMAcceptFastFailAsync( + CompletionStage cf, Executor executor, Consumer... actions) { requireNonNull(cf, "cf is null"); requireNonNull(executor, "executor is null"); - Function[] fns = requireArrayAndEleNonNull("fn", fn1, fn2, fn3); + requireArrayAndEleNonNull("action", actions); - return toNonMinCf(cf).thenCompose(v -> allTupleOf0(wrapFunctions(executor, null, fns), false)); + return toNonMinCf(cf).thenCompose(v -> allOfFastFail(wrapConsumers(executor, v, actions))); + } + + private static CompletableFuture[] wrapConsumers(Executor executor, T v, Consumer[] actions) { + @SuppressWarnings("unchecked") + CompletableFuture[] cfs = new CompletableFuture[actions.length]; + for (int i = 0; i < actions.length; i++) { + final int idx = i; + cfs[idx] = CompletableFuture.runAsync(() -> actions[idx].accept(v), executor); + } + return cfs; } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * is executed using the CompletableFuture's default asynchronous execution facility, - * with the values obtained by calling the given Functions - * (with the given stage's result as the argument to the given functions) - * in the same order of the given Functions arguments. + * executes the given actions using the CompletableFuture's default asynchronous execution facility. + *

+ * This method is the same as {@link #thenMRunAsync(CompletionStage, Runnable...)} + * except for the fast-fail behavior. * + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture + * @see CompletableFuture#thenRunAsync(Runnable) + * @see #allOfFastFail(CompletionStage[]) */ - public static CompletableFuture> allTupleOfThenMApplyAsync( - CompletionStage cf, Function fn1, - Function fn2, Function fn3, - Function fn4) { - return allTupleOfThenMApplyAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3, fn4); + public static CompletableFuture thenMRunFastFailAsync(CompletionStage cf, Runnable... actions) { + return thenMRunFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, actions); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * is executed using the given Executor, with the values obtained by calling the given Functions - * (with the given stage's result as the argument to the given functions) - * in the same order of the given Functions arguments. + * executes the given actions using the given Executor. + *

+ * This method is the same as {@link #thenMRunAsync(CompletionStage, Executor, Runnable...)} + * except for the fast-fail behavior. * + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture + * @see CompletableFuture#thenRunAsync(Runnable, Executor) + * @see #allOfFastFail(CompletionStage[]) */ - public static CompletableFuture> allTupleOfThenMApplyAsync( - CompletionStage cf, Executor executor, Function fn1, - Function fn2, Function fn3, - Function fn4) { + public static CompletableFuture thenMRunFastFailAsync( + CompletionStage cf, Executor executor, Runnable... actions) { requireNonNull(cf, "cf is null"); requireNonNull(executor, "executor is null"); - Function[] fns = requireArrayAndEleNonNull("fn", fn1, fn2, fn3, fn4); + requireArrayAndEleNonNull("action", actions); - return toNonMinCf(cf).thenCompose(v -> allTupleOf0(wrapFunctions(executor, null, fns), false)); + return toNonMinCf(cf).thenCompose(unused -> allOfFastFail(wrapActions(executor, actions))); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * is executed using the CompletableFuture's default asynchronous execution facility, - * with the values obtained by calling the given Functions - * (with the given stage's result as the argument to the given functions) - * in the same order of the given Functions arguments. + * executes the given actions using the given Executor. * + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture + * @see CompletableFuture#thenRunAsync(Runnable, Executor) + * @see #allOf(CompletionStage[]) */ - public static CompletableFuture> allTupleOfThenMApplyAsync( - CompletionStage cf, Function fn1, - Function fn2, Function fn3, - Function fn4, Function fn5) { - return allTupleOfThenMApplyAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3, fn4, fn5); + public static CompletableFuture thenMRunAsync(CompletionStage cf, Executor executor, Runnable... actions) { + requireNonNull(cf, "cf is null"); + requireNonNull(executor, "executor is null"); + requireArrayAndEleNonNull("action", actions); + + return toNonMinCf(cf).thenCompose(unused -> CompletableFuture.allOf(wrapActions(executor, actions))); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * is executed using the given Executor, with the values obtained by calling the given Functions - * (with the given stage's result as the argument to the given functions) - * in the same order of the given Functions arguments. + * executes the given actions using the CompletableFuture's default asynchronous execution facility. * + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture + * @see CompletableFuture#thenRunAsync(Runnable) + * @see #allOf(CompletionStage[]) */ - public static CompletableFuture> allTupleOfThenMApplyAsync( - CompletionStage cf, Executor executor, Function fn1, - Function fn2, Function fn3, - Function fn4, Function fn5) { - requireNonNull(cf, "cf is null"); - requireNonNull(executor, "executor is null"); - Function[] fns = requireArrayAndEleNonNull("fn", fn1, fn2, fn3, fn4, fn5); - - return toNonMinCf(cf).thenCompose(v -> allTupleOf0(wrapFunctions(executor, null, fns), false)); + public static CompletableFuture thenMRunAsync(CompletionStage cf, Runnable... actions) { + return thenMRunAsync(cf, AsyncPoolHolder.ASYNC_POOL, actions); } + // endregion + //////////////////////////////////////////////////////////// + // region## Then-Tuple-Multi-Actions(thenTupleM*) Methods + //////////////////////////////////////////////////////////// + /** * Returns a new CompletableFuture that, when the given stage completes normally, * is executed using the CompletableFuture's default asynchronous execution facility, @@ -1716,15 +1746,15 @@ public static CompletableFuturesame order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Function, Function)} * except for the fast-fail behavior. * * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyFastFailAsync( + public static CompletableFuture> thenTupleMApplyFastFailAsync( CompletionStage cf, Function fn1, Function fn2) { - return allTupleOfThenMApplyFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2); + return thenTupleMApplyFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2); } /** @@ -1733,12 +1763,12 @@ public static CompletableFuture> allTupleOfThenMApply * (with the given stage's result as the argument to the given functions) * in the same order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Executor, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Executor, Function, Function)} * except for the fast-fail behavior. * * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyFastFailAsync( + public static CompletableFuture> thenTupleMApplyFastFailAsync( CompletionStage cf, Executor executor, Function fn1, Function fn2) { requireNonNull(cf, "cf is null"); @@ -1755,15 +1785,15 @@ public static CompletableFuture> allTupleOfThenMApply * (with the given stage's result as the argument to the given functions) * in the same order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Function, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Function, Function, Function)} * except for the fast-fail behavior. * * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyFastFailAsync( + public static CompletableFuture> thenTupleMApplyFastFailAsync( CompletionStage cf, Function fn1, Function fn2, Function fn3) { - return allTupleOfThenMApplyFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3); + return thenTupleMApplyFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3); } /** @@ -1772,12 +1802,12 @@ public static CompletableFuture> allTupleOfTh * (with the given stage's result as the argument to the given functions) * in the same order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Executor, Function, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Executor, Function, Function, Function)} * except for the fast-fail behavior. * * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyFastFailAsync( + public static CompletableFuture> thenTupleMApplyFastFailAsync( CompletionStage cf, Executor executor, Function fn1, Function fn2, Function fn3) { requireNonNull(cf, "cf is null"); @@ -1794,16 +1824,16 @@ public static CompletableFuture> allTupleOfTh * (with the given stage's result as the argument to the given functions) * in the same order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Function, Function, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Function, Function, Function, Function)} * except for the fast-fail behavior. * * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyFastFailAsync( + public static CompletableFuture> thenTupleMApplyFastFailAsync( CompletionStage cf, Function fn1, Function fn2, Function fn3, Function fn4) { - return allTupleOfThenMApplyFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3, fn4); + return thenTupleMApplyFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3, fn4); } /** @@ -1812,12 +1842,12 @@ public static CompletableFuture> allT * (with the given stage's result as the argument to the given functions) * in the same order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Executor, Function, Function, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Executor, Function, Function, Function, Function)} * except for the fast-fail behavior. * * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyFastFailAsync( + public static CompletableFuture> thenTupleMApplyFastFailAsync( CompletionStage cf, Executor executor, Function fn1, Function fn2, Function fn3, Function fn4) { @@ -1835,16 +1865,16 @@ public static CompletableFuture> allT * (with the given stage's result as the argument to the given functions) * in the same order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Function, Function, Function, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Function, Function, Function, Function, Function)} * except for the fast-fail behavior. * * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyFastFailAsync( + public static CompletableFuture> thenTupleMApplyFastFailAsync( CompletionStage cf, Function fn1, Function fn2, Function fn3, Function fn4, Function fn5) { - return allTupleOfThenMApplyFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3, fn4, fn5); + return thenTupleMApplyFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3, fn4, fn5); } /** @@ -1853,12 +1883,12 @@ public static CompletableFuturesame order of the given Functions arguments. *

- * This method is the same as {@link #allTupleOfThenMApplyAsync(CompletionStage, Executor, Function, Function, Function, Function, Function)} + * This method is the same as {@link #thenTupleMApplyAsync(CompletionStage, Executor, Function, Function, Function, Function, Function)} * except for the fast-fail behavior. * * @return the new CompletableFuture */ - public static CompletableFuture> allTupleOfThenMApplyFastFailAsync( + public static CompletableFuture> thenTupleMApplyFastFailAsync( CompletionStage cf, Executor executor, Function fn1, Function fn2, Function fn3, Function fn4, Function fn5) { @@ -1869,160 +1899,140 @@ public static CompletableFuture allTupleOf0(wrapFunctions(executor, null, fns), false)); } - private static CompletableFuture[] wrapFunctions( - Executor executor, @Nullable T v, Function[] fns) { - @SuppressWarnings("unchecked") - CompletableFuture[] cfs = new CompletableFuture[fns.length]; - for (int i = 0; i < fns.length; i++) { - final int idx = i; - cfs[i] = CompletableFuture.supplyAsync(() -> fns[idx].apply(v), executor); - } - return cfs; - } - /** * Returns a new CompletableFuture that, when the given stage completes normally, * is executed using the CompletableFuture's default asynchronous execution facility, - * with the given stage's result as the argument to the given actions. + * with the values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the same order of the given Functions arguments. * - * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture */ - @SafeVarargs - public static CompletableFuture thenMAcceptAsync( - CompletionStage cf, Consumer... actions) { - return thenMAcceptAsync(cf, AsyncPoolHolder.ASYNC_POOL, actions); + public static CompletableFuture> thenTupleMApplyAsync( + CompletionStage cf, + Function fn1, Function fn2) { + return thenTupleMApplyAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * is executed using the given Executor, with the given stage's result as the argument to the given actions. + * is executed using the given Executor, with the values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the same order of the given Functions arguments. * - * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture */ - @SafeVarargs - public static CompletableFuture thenMAcceptAsync( - CompletionStage cf, Executor executor, Consumer... actions) { + public static CompletableFuture> thenTupleMApplyAsync( + CompletionStage cf, Executor executor, + Function fn1, Function fn2) { requireNonNull(cf, "cf is null"); requireNonNull(executor, "executor is null"); - requireArrayAndEleNonNull("action", actions); + Function[] fns = requireArrayAndEleNonNull("fn", fn1, fn2); - return toNonMinCf(cf).thenCompose(v -> CompletableFuture.allOf(wrapConsumers(executor, v, actions))); + return toNonMinCf(cf).thenCompose(v -> allTupleOf0(wrapFunctions(executor, null, fns), false)); } /** * Returns a new CompletableFuture that, when the given stage completes normally, * is executed using the CompletableFuture's default asynchronous execution facility, - * with the given stage's result as the argument to the given actions. - *

- * This method is the same as {@link #thenMAcceptAsync(CompletionStage, Consumer[])} - * except for the fast-fail behavior. + * with the values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the same order of the given Functions arguments. * - * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture */ - @SafeVarargs - public static CompletableFuture thenMAcceptFastFailAsync( - CompletionStage cf, Consumer... actions) { - return thenMAcceptFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, actions); + public static CompletableFuture> thenTupleMApplyAsync( + CompletionStage cf, Function fn1, + Function fn2, Function fn3) { + return thenTupleMApplyAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * is executed using the given Executor, with the given stage's result as the argument to the given actions. - *

- * This method is the same as {@link #thenMAcceptAsync(CompletionStage, Executor, Consumer[])} - * except for the fast-fail behavior. + * is executed using the given Executor, with the values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the same order of the given Functions arguments. * - * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture */ - @SafeVarargs - public static CompletableFuture thenMAcceptFastFailAsync( - CompletionStage cf, Executor executor, Consumer... actions) { + public static CompletableFuture> thenTupleMApplyAsync( + CompletionStage cf, Executor executor, Function fn1, + Function fn2, Function fn3) { requireNonNull(cf, "cf is null"); requireNonNull(executor, "executor is null"); - requireArrayAndEleNonNull("action", actions); - - return toNonMinCf(cf).thenCompose(v -> allOfFastFail(wrapConsumers(executor, v, actions))); - } + Function[] fns = requireArrayAndEleNonNull("fn", fn1, fn2, fn3); - private static CompletableFuture[] wrapConsumers(Executor executor, T v, Consumer[] actions) { - @SuppressWarnings("unchecked") - CompletableFuture[] cfs = new CompletableFuture[actions.length]; - for (int i = 0; i < actions.length; i++) { - final int idx = i; - cfs[idx] = CompletableFuture.runAsync(() -> actions[idx].accept(v), executor); - } - return cfs; + return toNonMinCf(cf).thenCompose(v -> allTupleOf0(wrapFunctions(executor, null, fns), false)); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * executes the given actions using the CompletableFuture's default asynchronous execution facility. - *

- * This method is the same as {@link #thenMRunAsync(CompletionStage, Runnable...)} - * except for the fast-fail behavior. + * is executed using the CompletableFuture's default asynchronous execution facility, + * with the values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the same order of the given Functions arguments. * - * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture - * @see CompletableFuture#thenRunAsync(Runnable) - * @see #allOfFastFail(CompletionStage[]) */ - public static CompletableFuture thenMRunFastFailAsync(CompletionStage cf, Runnable... actions) { - return thenMRunFastFailAsync(cf, AsyncPoolHolder.ASYNC_POOL, actions); + public static CompletableFuture> thenTupleMApplyAsync( + CompletionStage cf, Function fn1, + Function fn2, Function fn3, + Function fn4) { + return thenTupleMApplyAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3, fn4); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * executes the given actions using the given Executor. - *

- * This method is the same as {@link #thenMRunAsync(CompletionStage, Executor, Runnable...)} - * except for the fast-fail behavior. + * is executed using the given Executor, with the values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the same order of the given Functions arguments. * - * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture - * @see CompletableFuture#thenRunAsync(Runnable, Executor) - * @see #allOfFastFail(CompletionStage[]) */ - public static CompletableFuture thenMRunFastFailAsync( - CompletionStage cf, Executor executor, Runnable... actions) { + public static CompletableFuture> thenTupleMApplyAsync( + CompletionStage cf, Executor executor, Function fn1, + Function fn2, Function fn3, + Function fn4) { requireNonNull(cf, "cf is null"); requireNonNull(executor, "executor is null"); - requireArrayAndEleNonNull("action", actions); + Function[] fns = requireArrayAndEleNonNull("fn", fn1, fn2, fn3, fn4); - return toNonMinCf(cf).thenCompose(unused -> allOfFastFail(wrapActions(executor, actions))); + return toNonMinCf(cf).thenCompose(v -> allTupleOf0(wrapFunctions(executor, null, fns), false)); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * executes the given actions using the given Executor. + * is executed using the CompletableFuture's default asynchronous execution facility, + * with the values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the same order of the given Functions arguments. * - * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture - * @see CompletableFuture#thenRunAsync(Runnable, Executor) - * @see #allOf(CompletionStage[]) */ - public static CompletableFuture thenMRunAsync(CompletionStage cf, Executor executor, Runnable... actions) { - requireNonNull(cf, "cf is null"); - requireNonNull(executor, "executor is null"); - requireArrayAndEleNonNull("action", actions); - - return toNonMinCf(cf).thenCompose(unused -> CompletableFuture.allOf(wrapActions(executor, actions))); + public static CompletableFuture> thenTupleMApplyAsync( + CompletionStage cf, Function fn1, + Function fn2, Function fn3, + Function fn4, Function fn5) { + return thenTupleMApplyAsync(cf, AsyncPoolHolder.ASYNC_POOL, fn1, fn2, fn3, fn4, fn5); } /** * Returns a new CompletableFuture that, when the given stage completes normally, - * executes the given actions using the CompletableFuture's default asynchronous execution facility. + * is executed using the given Executor, with the values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the same order of the given Functions arguments. * - * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture - * @see CompletableFuture#thenRunAsync(Runnable) - * @see #allOf(CompletionStage[]) */ - public static CompletableFuture thenMRunAsync(CompletionStage cf, Runnable... actions) { - return thenMRunAsync(cf, AsyncPoolHolder.ASYNC_POOL, actions); + public static CompletableFuture> thenTupleMApplyAsync( + CompletionStage cf, Executor executor, Function fn1, + Function fn2, Function fn3, + Function fn4, Function fn5) { + requireNonNull(cf, "cf is null"); + requireNonNull(executor, "executor is null"); + Function[] fns = requireArrayAndEleNonNull("fn", fn1, fn2, fn3, fn4, fn5); + + return toNonMinCf(cf).thenCompose(v -> allTupleOf0(wrapFunctions(executor, null, fns), false)); } // endregion diff --git a/cffu-core/src/test/java/io/foldright/cffu/CffuFactoryTest.java b/cffu-core/src/test/java/io/foldright/cffu/CffuFactoryTest.java index 245714fc..ff68cd8b 100644 --- a/cffu-core/src/test/java/io/foldright/cffu/CffuFactoryTest.java +++ b/cffu-core/src/test/java/io/foldright/cffu/CffuFactoryTest.java @@ -627,7 +627,7 @@ void test_mostTupleOfSuccess() throws Exception { } @Test - void test_allTupleOfMSupplyAsync() throws Exception { + void test_tupleMSupplyAsync() throws Exception { final Supplier supplier_n = () -> { sleep(100); return n; @@ -649,21 +649,21 @@ void test_allTupleOfMSupplyAsync() throws Exception { sleep(100); return n+n; }; - assertEquals(Tuple2.of(n, s), cffuFactory.allTupleOfMSupplyAsync(supplier_n, supplier_s).get()); - assertEquals(Tuple2.of(n, s), cffuFactory.allTupleOfMSupplyFastFailAsync(supplier_n, supplier_s).get()); + assertEquals(Tuple2.of(n, s), cffuFactory.tupleMSupplyAsync(supplier_n, supplier_s).get()); + assertEquals(Tuple2.of(n, s), cffuFactory.tupleMSupplyFastFailAsync(supplier_n, supplier_s).get()); - assertEquals(Tuple3.of(n, s, d), cffuFactory.allTupleOfMSupplyAsync(supplier_n, supplier_s, supplier_d).get()); - assertEquals(Tuple3.of(n, s, d), cffuFactory.allTupleOfMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d).get()); + assertEquals(Tuple3.of(n, s, d), cffuFactory.tupleMSupplyAsync(supplier_n, supplier_s, supplier_d).get()); + assertEquals(Tuple3.of(n, s, d), cffuFactory.tupleMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d).get()); - assertEquals(Tuple4.of(n, s, d, anotherN), cffuFactory.allTupleOfMSupplyAsync(supplier_n, supplier_s, supplier_d, supplier_an).get()); - assertEquals(Tuple4.of(n, s, d, anotherN), cffuFactory.allTupleOfMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d, supplier_an).get()); + assertEquals(Tuple4.of(n, s, d, anotherN), cffuFactory.tupleMSupplyAsync(supplier_n, supplier_s, supplier_d, supplier_an).get()); + assertEquals(Tuple4.of(n, s, d, anotherN), cffuFactory.tupleMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d, supplier_an).get()); - assertEquals(Tuple5.of(n, s, d, anotherN, n + n), cffuFactory.allTupleOfMSupplyAsync(supplier_n, supplier_s, supplier_d, supplier_an, supplier_nn).get()); - assertEquals(Tuple5.of(n, s, d, anotherN, n + n), cffuFactory.allTupleOfMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d, supplier_an, supplier_nn).get()); + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), cffuFactory.tupleMSupplyAsync(supplier_n, supplier_s, supplier_d, supplier_an, supplier_nn).get()); + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), cffuFactory.tupleMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d, supplier_an, supplier_nn).get()); } @Test - void test_allTupleOfThenMApplyAsync() throws Exception { + void test_thenTupleMApplyAsync() throws Exception { final CompletableFuture completed = completedFuture(n); final Function function_n = (x) -> { sleep(100); @@ -687,17 +687,17 @@ void test_allTupleOfThenMApplyAsync() throws Exception { sleep(100); return n+n; }; - assertEquals(Tuple2.of(n, s), cffuFactory.allTupleOfThenMApplyAsync(completed,function_n, function_s).get()); - assertEquals(Tuple2.of(n, s), cffuFactory.allTupleOfThenMApplyFastFailAsync(completed,function_n, function_s).get()); + assertEquals(Tuple2.of(n, s), cffuFactory.thenTupleMApplyAsync(completed,function_n, function_s).get()); + assertEquals(Tuple2.of(n, s), cffuFactory.thenTupleMApplyFastFailAsync(completed,function_n, function_s).get()); - assertEquals(Tuple3.of(n, s, d), cffuFactory.allTupleOfThenMApplyAsync(completed,function_n, function_s, function_d).get()); - assertEquals(Tuple3.of(n, s, d), cffuFactory.allTupleOfThenMApplyFastFailAsync(completed,function_n, function_s, function_d).get()); + assertEquals(Tuple3.of(n, s, d), cffuFactory.thenTupleMApplyAsync(completed,function_n, function_s, function_d).get()); + assertEquals(Tuple3.of(n, s, d), cffuFactory.thenTupleMApplyFastFailAsync(completed,function_n, function_s, function_d).get()); - assertEquals(Tuple4.of(n, s, d, anotherN), cffuFactory.allTupleOfThenMApplyAsync(completed,function_n, function_s, function_d, function_an).get()); - assertEquals(Tuple4.of(n, s, d, anotherN), cffuFactory.allTupleOfThenMApplyFastFailAsync(completed,function_n, function_s, function_d, function_an).get()); + assertEquals(Tuple4.of(n, s, d, anotherN), cffuFactory.thenTupleMApplyAsync(completed,function_n, function_s, function_d, function_an).get()); + assertEquals(Tuple4.of(n, s, d, anotherN), cffuFactory.thenTupleMApplyFastFailAsync(completed,function_n, function_s, function_d, function_an).get()); - assertEquals(Tuple5.of(n, s, d, anotherN, n + n), cffuFactory.allTupleOfThenMApplyAsync(completed,function_n, function_s, function_d, function_an, function_nn).get()); - assertEquals(Tuple5.of(n, s, d, anotherN, n + n), cffuFactory.allTupleOfThenMApplyFastFailAsync(completed,function_n, function_s, function_d, function_an, function_nn).get()); + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), cffuFactory.thenTupleMApplyAsync(completed,function_n, function_s, function_d, function_an, function_nn).get()); + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), cffuFactory.thenTupleMApplyFastFailAsync(completed,function_n, function_s, function_d, function_an, function_nn).get()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/cffu-core/src/test/java/io/foldright/cffu/CompletableFutureUtilsTest.java b/cffu-core/src/test/java/io/foldright/cffu/CompletableFutureUtilsTest.java index 92848b85..9a5a9e16 100644 --- a/cffu-core/src/test/java/io/foldright/cffu/CompletableFutureUtilsTest.java +++ b/cffu-core/src/test/java/io/foldright/cffu/CompletableFutureUtilsTest.java @@ -751,7 +751,7 @@ void test_allTupleOf_NotFastFail() throws Exception { @Test - void test_allTupleOfMSupplyAsync() throws Exception { + void test_tupleMSupplyAsync() throws Exception { final Supplier supplier_n = () -> { sleep(100); return n; @@ -773,22 +773,22 @@ void test_allTupleOfMSupplyAsync() throws Exception { sleep(100); return n+n; }; - assertEquals(Tuple2.of(n, s), allTupleOfMSupplyAsync(supplier_n, supplier_s).get()); - assertEquals(Tuple2.of(n, s), allTupleOfMSupplyFastFailAsync(supplier_n, supplier_s).get()); + assertEquals(Tuple2.of(n, s), tupleMSupplyAsync(supplier_n, supplier_s).get()); + assertEquals(Tuple2.of(n, s), tupleMSupplyFastFailAsync(supplier_n, supplier_s).get()); - assertEquals(Tuple3.of(n, s, d), allTupleOfMSupplyAsync(supplier_n, supplier_s, supplier_d).get()); - assertEquals(Tuple3.of(n, s, d), allTupleOfMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d).get()); + assertEquals(Tuple3.of(n, s, d), tupleMSupplyAsync(supplier_n, supplier_s, supplier_d).get()); + assertEquals(Tuple3.of(n, s, d), tupleMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d).get()); - assertEquals(Tuple4.of(n, s, d, anotherN), allTupleOfMSupplyAsync(supplier_n, supplier_s, supplier_d, supplier_an).get()); - assertEquals(Tuple4.of(n, s, d, anotherN), allTupleOfMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d, supplier_an).get()); + assertEquals(Tuple4.of(n, s, d, anotherN), tupleMSupplyAsync(supplier_n, supplier_s, supplier_d, supplier_an).get()); + assertEquals(Tuple4.of(n, s, d, anotherN), tupleMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d, supplier_an).get()); - assertEquals(Tuple5.of(n, s, d, anotherN, n + n), allTupleOfMSupplyAsync(supplier_n, supplier_s, supplier_d, supplier_an, supplier_nn).get()); - assertEquals(Tuple5.of(n, s, d, anotherN, n + n), allTupleOfMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d, supplier_an, supplier_nn).get()); + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), tupleMSupplyAsync(supplier_n, supplier_s, supplier_d, supplier_an, supplier_nn).get()); + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), tupleMSupplyFastFailAsync(supplier_n, supplier_s, supplier_d, supplier_an, supplier_nn).get()); } @Test - void test_allTupleOfThenMApplyAsync() throws Exception { + void test_thenTupleMApplyAsync() throws Exception { final CompletableFuture completed = completedFuture(n); final Function function_n = (x) -> { sleep(100); @@ -812,17 +812,17 @@ void test_allTupleOfThenMApplyAsync() throws Exception { sleep(100); return n+n; }; - assertEquals(Tuple2.of(n, s), allTupleOfThenMApplyAsync(completed,function_n, function_s).get()); - assertEquals(Tuple2.of(n, s), allTupleOfThenMApplyFastFailAsync(completed,function_n, function_s).get()); + assertEquals(Tuple2.of(n, s), thenTupleMApplyAsync(completed,function_n, function_s).get()); + assertEquals(Tuple2.of(n, s), thenTupleMApplyFastFailAsync(completed,function_n, function_s).get()); - assertEquals(Tuple3.of(n, s, d), allTupleOfThenMApplyAsync(completed,function_n, function_s, function_d).get()); - assertEquals(Tuple3.of(n, s, d), allTupleOfThenMApplyFastFailAsync(completed,function_n, function_s, function_d).get()); + assertEquals(Tuple3.of(n, s, d), thenTupleMApplyAsync(completed,function_n, function_s, function_d).get()); + assertEquals(Tuple3.of(n, s, d), thenTupleMApplyFastFailAsync(completed,function_n, function_s, function_d).get()); - assertEquals(Tuple4.of(n, s, d, anotherN), allTupleOfThenMApplyAsync(completed,function_n, function_s, function_d, function_an).get()); - assertEquals(Tuple4.of(n, s, d, anotherN), allTupleOfThenMApplyFastFailAsync(completed,function_n, function_s, function_d, function_an).get()); + assertEquals(Tuple4.of(n, s, d, anotherN), thenTupleMApplyAsync(completed,function_n, function_s, function_d, function_an).get()); + assertEquals(Tuple4.of(n, s, d, anotherN), thenTupleMApplyFastFailAsync(completed,function_n, function_s, function_d, function_an).get()); - assertEquals(Tuple5.of(n, s, d, anotherN, n + n), allTupleOfThenMApplyAsync(completed,function_n, function_s, function_d, function_an, function_nn).get()); - assertEquals(Tuple5.of(n, s, d, anotherN, n + n), allTupleOfThenMApplyFastFailAsync(completed,function_n, function_s, function_d, function_an, function_nn).get()); + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), thenTupleMApplyAsync(completed,function_n, function_s, function_d, function_an, function_nn).get()); + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), thenTupleMApplyFastFailAsync(completed,function_n, function_s, function_d, function_an, function_nn).get()); } @Test