From 7131ca462b8e5fe2f071c4b172dbbd6f2cb6a7f0 Mon Sep 17 00:00:00 2001 From: huhaosumail <995483610@qq.com> Date: Tue, 25 Jun 2024 17:56:16 +0800 Subject: [PATCH] =?UTF-8?q?`CompletableFutureUtils`=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=9A=84`tupleMSupplyMostSuccessAsync`?= =?UTF-8?q?=E4=B8=8E`thenTupleMApplyMostSuccessAsync`=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E7=9B=B8=E5=85=B3=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cffu/CompletableFutureUtils.java | 338 ++++++++++++++++-- .../cffu/CompletableFutureUtilsTest.java | 43 +++ 2 files changed, 358 insertions(+), 23 deletions(-) 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 622ef804..05c1c475 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -429,12 +429,36 @@ public static <T1, T2, T3, T4, T5> CompletableFuture<Tuple5<T1, T2, T3, T4, T5>> /** * 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 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) * in the <strong>same order</strong> of the given Suppliers arguments. * <p> - * This method is the same as {@link #tupleMSupplyAsync(Executor, Supplier, Supplier)} except for the most-success 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 timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T1, T2> CompletableFuture<Tuple2<T1, T2>> tupleMSupplyMostSuccessAsync( + long timeout, TimeUnit unit, + Supplier<? extends T1> supplier1, Supplier<? extends T2> supplier2) { + return tupleMSupplyMostSuccessAsync(AsyncPoolHolder.ASYNC_POOL, timeout, unit, supplier1, supplier2); + } + + /** + * 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) + * in the <strong>same order</strong> of the given Suppliers arguments. + * <p> + * If the given supplier is successful in the given time, the return result is the completed value; + * Otherwise the given valueIfNotSuccess. + * + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter * @return the new CompletableFuture */ public static <T1, T2> CompletableFuture<Tuple2<T1, T2>> tupleMSupplyMostSuccessAsync( @@ -449,13 +473,36 @@ public static <T1, T2> CompletableFuture<Tuple2<T1, T2>> tupleMSupplyMostSuccess /** * 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 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) * in the <strong>same order</strong> of the given Suppliers arguments. * <p> - * This method is the same as {@link #tupleMSupplyAsync(Executor, Supplier, Supplier, Supplier)} - * except for the most-success 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 timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T1, T2, T3> CompletableFuture<Tuple3<T1, T2, T3>> tupleMSupplyMostSuccessAsync( + long timeout, TimeUnit unit, + Supplier<? extends T1> supplier1, Supplier<? extends T2> supplier2, Supplier<? extends T3> supplier3) { + return tupleMSupplyMostSuccessAsync(AsyncPoolHolder.ASYNC_POOL, timeout, unit, supplier1, supplier2, supplier3); + } + + /** + * 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) + * in the <strong>same order</strong> of the given Suppliers arguments. + * <p> + * If the given supplier is successful in the given time, the return result is the completed value; + * Otherwise the given valueIfNotSuccess. + * + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter * @return the new CompletableFuture */ public static <T1, T2, T3> CompletableFuture<Tuple3<T1, T2, T3>> tupleMSupplyMostSuccessAsync( @@ -470,13 +517,36 @@ public static <T1, T2, T3> CompletableFuture<Tuple3<T1, T2, T3>> tupleMSupplyMos /** * 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 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) * in the <strong>same order</strong> of the given Suppliers arguments. * <p> - * This method is the same as {@link #tupleMSupplyAsync(Executor, Supplier, Supplier, Supplier, Supplier)} - * except for the most-success 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 timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T1, T2, T3, T4> CompletableFuture<Tuple4<T1, T2, T3, T4>> tupleMSupplyMostSuccessAsync( + long timeout, TimeUnit unit, Supplier<? extends T1> supplier1, + Supplier<? extends T2> supplier2, Supplier<? extends T3> supplier3, Supplier<? extends T4> supplier4) { + return tupleMSupplyMostSuccessAsync(AsyncPoolHolder.ASYNC_POOL, timeout, unit, supplier1, supplier2, supplier3, supplier4); + } + + /** + * 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) + * in the <strong>same order</strong> of the given Suppliers arguments. + * <p> + * If the given supplier is successful in the given time, the return result is the completed value; + * Otherwise the given valueIfNotSuccess. + * + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter * @return the new CompletableFuture */ public static <T1, T2, T3, T4> CompletableFuture<Tuple4<T1, T2, T3, T4>> tupleMSupplyMostSuccessAsync( @@ -491,13 +561,37 @@ public static <T1, T2, T3, T4> CompletableFuture<Tuple4<T1, T2, T3, T4>> tupleMS /** * 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 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) * in the <strong>same order</strong> of the given Suppliers arguments. * <p> - * This method is the same as {@link #tupleMSupplyAsync(Executor, Supplier, Supplier, Supplier, Supplier, Supplier)} - * except for the most-success 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 timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T1, T2, T3, T4, T5> CompletableFuture<Tuple5<T1, T2, T3, T4, T5>> tupleMSupplyMostSuccessAsync( + long timeout, TimeUnit unit, Supplier<? extends T1> supplier1, + Supplier<? extends T2> supplier2, Supplier<? extends T3> supplier3, + Supplier<? extends T4> supplier4, Supplier<? extends T5> supplier5) { + return tupleMSupplyMostSuccessAsync(AsyncPoolHolder.ASYNC_POOL, timeout, unit, supplier1, supplier2, supplier3, supplier4, supplier5); + } + + /** + * 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) + * in the <strong>same order</strong> of the given Suppliers arguments. + * <p> + * If the given supplier is successful in the given time, the return result is the completed value; + * Otherwise the given valueIfNotSuccess. + * + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter * @return the new CompletableFuture */ public static <T1, T2, T3, T4, T5> CompletableFuture<Tuple5<T1, T2, T3, T4, T5>> tupleMSupplyMostSuccessAsync( @@ -1555,8 +1649,9 @@ public static <T, U> CompletableFuture<List<U>> thenMApplyFastFailAsync( * This method is the same as {@link #thenMApplyAsync(CompletionStage, Executor, Function[])} * except for the fast-fail behavior. * - * @param fns the functions to use to compute the values of the returned CompletableFuture - * @param <U> the functions' return type + * @param fns the functions to use to compute the values of the returned CompletableFuture + * @param executor the executor to use for asynchronous execution + * @param <U> the functions' return type * @return the new CompletableFuture */ @SafeVarargs @@ -1648,8 +1743,9 @@ public static <T, U> CompletableFuture<List<U>> thenMApplyAsync( * (with the given stage's result as the argument to the given functions) * in the <strong>same order</strong> of the given Functions arguments. * - * @param fns the functions to use to compute the values of the returned CompletableFuture - * @param <U> the functions' return type + * @param executor the executor to use for asynchronous execution + * @param fns the functions to use to compute the values of the returned CompletableFuture + * @param <U> the functions' return type * @return the new CompletableFuture */ @SafeVarargs @@ -1691,7 +1787,8 @@ public static <T> CompletableFuture<Void> thenMAcceptAsync( * 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. * - * @param actions the actions to perform before completing the returned CompletableFuture + * @param executor the executor to use for asynchronous execution + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture */ @SafeVarargs @@ -1728,7 +1825,8 @@ public static <T> CompletableFuture<Void> thenMAcceptFastFailAsync( * 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 + * @param executor the executor to use for asynchronous execution + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture */ @SafeVarargs @@ -1774,7 +1872,8 @@ public static CompletableFuture<Void> thenMRunFastFailAsync(CompletionStage<?> c * 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 + * @param executor the executor to use for asynchronous execution + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture * @see CompletableFuture#thenRunAsync(Runnable, Executor) * @see #allOfFastFail(CompletionStage[]) @@ -1805,7 +1904,8 @@ public static CompletableFuture<Void> thenMRunAsync(CompletionStage<?> cf, Runna * Returns a new CompletableFuture that, when the given stage completes normally, * executes the given actions using the given Executor. * - * @param actions the actions to perform before completing the returned CompletableFuture + * @param executor the executor to use for asynchronous execution + * @param actions the actions to perform before completing the returned CompletableFuture * @return the new CompletableFuture * @see CompletableFuture#thenRunAsync(Runnable, Executor) * @see #allOf(CompletionStage[]) @@ -1983,6 +2083,198 @@ public static <T, U1, U2, U3, U4, U5> CompletableFuture<Tuple5<U1, U2, U3, U4, U return f_toCf(cf).thenCompose(v -> allTupleOf0(true, wrapFunctions(executor, v, fns))); } + /** + * Returns a new CompletableFuture that, when the given stage completes normally, + * is executed using the CompletableFuture's default asynchronous execution facility, + * with the most values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the given time({@code timeout}, aka as many results as possible in the given time) + * in the <strong>same order</strong> of the given Functions arguments. + * <p> + * If the given function is successful in the given time, the return result is the completed value; + * Otherwise the given valueIfNotSuccess. + * + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T, U1, U2> CompletableFuture<Tuple2<U1, U2>> thenTupleMApplyMostSuccessAsync( + CompletionStage<? extends T> cf, + long timeout, TimeUnit unit, Function<? super T, ? extends U1> fn1, Function<? super T, ? extends U2> fn2) { + return thenTupleMApplyMostSuccessAsync(cf, AsyncPoolHolder.ASYNC_POOL, timeout, unit, fn1, fn2); + } + + /** + * Returns a new CompletableFuture that, when the given stage completes normally, + * is executed using the CompletableFuture's default asynchronous execution facility, + * with the most values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the given time({@code timeout}, aka as many results as possible in the given time) + * in the <strong>same order</strong> of the given Functions arguments. + * <p> + * If the given function 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 timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T, U1, U2> CompletableFuture<Tuple2<U1, U2>> thenTupleMApplyMostSuccessAsync( + CompletionStage<? extends T> cf, Executor executor, long timeout, TimeUnit unit, Function<? super T, ? extends U1> fn1, Function<? super T, ? extends U2> fn2) { + requireNonNull(executor, "executor is null"); + requireNonNull(unit, "unit is null"); + requireArrayAndEleNonNull("fn", fn1, fn2); + + return f_toCf(cf).thenCompose(v -> mostTupleOfSuccess0(executor, timeout, unit, CompletableFuture.supplyAsync(() -> fn1.apply(v), executor), CompletableFuture.supplyAsync(() -> fn2.apply(v), executor))); + } + + /** + * Returns a new CompletableFuture that, when the given stage completes normally, + * is executed using the CompletableFuture's default asynchronous execution facility, + * with the most values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the given time({@code timeout}, aka as many results as possible in the given time) + * in the <strong>same order</strong> of the given Functions arguments. + * <p> + * If the given function is successful in the given time, the return result is the completed value; + * Otherwise the given valueIfNotSuccess. + * + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T, U1, U2, U3> CompletableFuture<Tuple3<U1, U2, U3>> thenTupleMApplyMostSuccessAsync( + CompletionStage<? extends T> cf, + long timeout, TimeUnit unit, Function<? super T, ? extends U1> fn1, Function<? super T, ? extends U2> fn2, Function<? super T, ? extends U3> fn3) { + return thenTupleMApplyMostSuccessAsync(cf, AsyncPoolHolder.ASYNC_POOL, timeout, unit, fn1, fn2, fn3); + } + + /** + * Returns a new CompletableFuture that, when the given stage completes normally, + * is executed using the CompletableFuture's default asynchronous execution facility, + * with the most values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the given time({@code timeout}, aka as many results as possible in the given time) + * in the <strong>same order</strong> of the given Functions arguments. + * <p> + * If the given function 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 timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T, U1, U2, U3> CompletableFuture<Tuple3<U1, U2, U3>> thenTupleMApplyMostSuccessAsync( + CompletionStage<? extends T> cf, Executor executor, long timeout, TimeUnit unit, Function<? super T, ? extends U1> fn1, Function<? super T, ? extends U2> fn2, Function<? super T, ? extends U3> fn3) { + requireNonNull(executor, "executor is null"); + requireNonNull(unit, "unit is null"); + requireArrayAndEleNonNull("fn", fn1, fn2, fn3); + + return f_toCf(cf).thenCompose(v -> mostTupleOfSuccess0(executor, timeout, unit, CompletableFuture.supplyAsync(() -> fn1.apply(v), executor), + CompletableFuture.supplyAsync(() -> fn2.apply(v), executor), CompletableFuture.supplyAsync(() -> fn3.apply(v), executor))); + } + + /** + * Returns a new CompletableFuture that, when the given stage completes normally, + * is executed using the CompletableFuture's default asynchronous execution facility, + * with the most values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the given time({@code timeout}, aka as many results as possible in the given time) + * in the <strong>same order</strong> of the given Functions arguments. + * <p> + * If the given function is successful in the given time, the return result is the completed value; + * Otherwise the given valueIfNotSuccess. + * + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T, U1, U2, U3, U4> CompletableFuture<Tuple4<U1, U2, U3, U4>> thenTupleMApplyMostSuccessAsync( + CompletionStage<? extends T> cf, long timeout, TimeUnit unit, Function<? super T, ? extends U1> fn1, + Function<? super T, ? extends U2> fn2, Function<? super T, ? extends U3> fn3, Function<? super T, ? extends U4> fn4) { + return thenTupleMApplyMostSuccessAsync(cf, AsyncPoolHolder.ASYNC_POOL, timeout, unit, fn1, fn2, fn3, fn4); + } + + /** + * Returns a new CompletableFuture that, when the given stage completes normally, + * is executed using the CompletableFuture's default asynchronous execution facility, + * with the most values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the given time({@code timeout}, aka as many results as possible in the given time) + * in the <strong>same order</strong> of the given Functions arguments. + * <p> + * If the given function 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 timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T, U1, U2, U3, U4> CompletableFuture<Tuple4<U1, U2, U3, U4>> thenTupleMApplyMostSuccessAsync( + CompletionStage<? extends T> cf, Executor executor, long timeout, TimeUnit unit, Function<? super T, ? extends U1> fn1, + Function<? super T, ? extends U2> fn2, Function<? super T, ? extends U3> fn3, Function<? super T, ? extends U4> fn4) { + requireNonNull(executor, "executor is null"); + requireNonNull(unit, "unit is null"); + requireArrayAndEleNonNull("fn", fn1, fn2, fn3, fn4); + + return f_toCf(cf).thenCompose(v -> mostTupleOfSuccess0(executor, timeout, unit, CompletableFuture.supplyAsync(() -> fn1.apply(v), executor), + CompletableFuture.supplyAsync(() -> fn2.apply(v), executor), CompletableFuture.supplyAsync(() -> fn3.apply(v), executor), CompletableFuture.supplyAsync(() -> fn4.apply(v), executor))); + } + + /** + * Returns a new CompletableFuture that, when the given stage completes normally, + * is executed using the CompletableFuture's default asynchronous execution facility, + * with the most values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the given time({@code timeout}, aka as many results as possible in the given time) + * in the <strong>same order</strong> of the given Functions arguments. + * <p> + * If the given function is successful in the given time, the return result is the completed value; + * Otherwise the given valueIfNotSuccess. + * + * @param timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T, U1, U2, U3, U4, U5> CompletableFuture<Tuple5<U1, U2, U3, U4, U5>> thenTupleMApplyMostSuccessAsync( + CompletionStage<? extends T> cf, long timeout, TimeUnit unit, Function<? super T, ? extends U1> fn1, + Function<? super T, ? extends U2> fn2, Function<? super T, ? extends U3> fn3, Function<? super T, ? extends U4> fn4, + Function<? super T, ? extends U5> fn5) { + return thenTupleMApplyMostSuccessAsync(cf, AsyncPoolHolder.ASYNC_POOL, timeout, unit, fn1, fn2, fn3, fn4, fn5); + } + + /** + * Returns a new CompletableFuture that, when the given stage completes normally, + * is executed using the CompletableFuture's default asynchronous execution facility, + * with the most values obtained by calling the given Functions + * (with the given stage's result as the argument to the given functions) + * in the given time({@code timeout}, aka as many results as possible in the given time) + * in the <strong>same order</strong> of the given Functions arguments. + * <p> + * If the given function 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 timeout how long to wait in units of {@code unit} + * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter + * @return the new CompletableFuture + */ + public static <T, U1, U2, U3, U4, U5> CompletableFuture<Tuple5<U1, U2, U3, U4, U5>> thenTupleMApplyMostSuccessAsync( + CompletionStage<? extends T> cf, Executor executor, long timeout, TimeUnit unit, Function<? super T, ? extends U1> fn1, + Function<? super T, ? extends U2> fn2, Function<? super T, ? extends U3> fn3, Function<? super T, ? extends U4> fn4, + Function<? super T, ? extends U5> fn5) { + requireNonNull(executor, "executor is null"); + requireNonNull(unit, "unit is null"); + requireArrayAndEleNonNull("fn", fn1, fn2, fn3, fn4, fn5); + + return f_toCf(cf).thenCompose(v -> mostTupleOfSuccess0(executor, timeout, unit, CompletableFuture.supplyAsync(() -> fn1.apply(v), executor), + CompletableFuture.supplyAsync(() -> fn2.apply(v), executor), CompletableFuture.supplyAsync(() -> fn3.apply(v), executor), + CompletableFuture.supplyAsync(() -> fn4.apply(v), executor), CompletableFuture.supplyAsync(() -> fn5.apply(v), executor))); + } + /** * Returns a new CompletableFuture that, when the given stage completes normally, * is executed using the CompletableFuture's default asynchronous execution facility, 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 9ecf9a45..70cd8112 100644 --- a/cffu-core/src/test/java/io/foldright/cffu/CompletableFutureUtilsTest.java +++ b/cffu-core/src/test/java/io/foldright/cffu/CompletableFutureUtilsTest.java @@ -809,15 +809,58 @@ void test_tupleMSupplyMostSuccessAsync() throws Exception { sleep(10); return n + n; }; + assertEquals(Tuple2.of(n, s), tupleMSupplyMostSuccessAsync(100, TimeUnit.MILLISECONDS, supplier_n, supplier_s).get()); assertEquals(Tuple2.of(n, s), tupleMSupplyMostSuccessAsync(defaultExecutor(), 100, TimeUnit.MILLISECONDS, supplier_n, supplier_s).get()); + assertEquals(Tuple3.of(n, s, d), tupleMSupplyMostSuccessAsync(100, TimeUnit.MILLISECONDS, supplier_n, supplier_s, supplier_d).get()); assertEquals(Tuple3.of(n, s, d), tupleMSupplyMostSuccessAsync(defaultExecutor(), 100, TimeUnit.MILLISECONDS, supplier_n, supplier_s, supplier_d).get()); + assertEquals(Tuple4.of(n, s, d, anotherN), tupleMSupplyMostSuccessAsync(100, TimeUnit.MILLISECONDS, supplier_n, supplier_s, supplier_d, supplier_an).get()); assertEquals(Tuple4.of(n, s, d, anotherN), tupleMSupplyMostSuccessAsync(defaultExecutor(), 100, TimeUnit.MILLISECONDS, supplier_n, supplier_s, supplier_d, supplier_an).get()); + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), tupleMSupplyMostSuccessAsync(100, TimeUnit.MILLISECONDS, supplier_n, supplier_s, supplier_d, supplier_an, supplier_nn).get()); assertEquals(Tuple5.of(n, s, d, anotherN, n + n), tupleMSupplyMostSuccessAsync(defaultExecutor(), 100, TimeUnit.MILLISECONDS, supplier_n, supplier_s, supplier_d, supplier_an, supplier_nn).get()); } + + @Test + void test_tupleMApplyMostSuccessAsync() throws Exception { + final CompletableFuture<Integer> completed = completedFuture(n); + final Function<Integer, Integer> function_n = (x) -> { + sleep(100); + return n; + }; + + final Function<Integer, String> function_s = (x) -> { + sleep(100); + return s; + }; + + final Function<Integer, Double> function_d = (x) -> { + sleep(100); + return d; + }; + final Function<Integer, Integer> function_an = (x) -> { + sleep(100); + return anotherN; + }; + final Function<Integer, Integer> function_nn = (x) -> { + sleep(100); + return n + n; + }; + assertEquals(Tuple2.of(n, s), thenTupleMApplyMostSuccessAsync(completed, 500, TimeUnit.MILLISECONDS, function_n, function_s).get()); + assertEquals(Tuple2.of(n, s), thenTupleMApplyMostSuccessAsync(completed, defaultExecutor(), 500, TimeUnit.MILLISECONDS, function_n, function_s).get()); + + assertEquals(Tuple3.of(n, s, d), thenTupleMApplyMostSuccessAsync(completed, 500, TimeUnit.MILLISECONDS, function_n, function_s, function_d).get()); + assertEquals(Tuple3.of(n, s, d), thenTupleMApplyMostSuccessAsync(completed, defaultExecutor(), 500, TimeUnit.MILLISECONDS, function_n, function_s, function_d).get()); + + assertEquals(Tuple4.of(n, s, d, anotherN), thenTupleMApplyMostSuccessAsync(completed, 500, TimeUnit.MILLISECONDS, function_n, function_s, function_d, function_an).get()); + assertEquals(Tuple4.of(n, s, d, anotherN), thenTupleMApplyMostSuccessAsync(completed, defaultExecutor(), 500, TimeUnit.MILLISECONDS, function_n, function_s, function_d, function_an).get()); + + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), thenTupleMApplyMostSuccessAsync(completed, 500, TimeUnit.MILLISECONDS, function_n, function_s, function_d, function_an, function_nn).get()); + assertEquals(Tuple5.of(n, s, d, anotherN, n + n), thenTupleMApplyMostSuccessAsync(completed, defaultExecutor(), 500, TimeUnit.MILLISECONDS, function_n, function_s, function_d, function_an, function_nn).get()); + } + @Test void test_thenTupleMApplyAsync() throws Exception { final CompletableFuture<Integer> completed = completedFuture(n);