From 4afd763ec7999968a31c17ac46e50fd8a150c5ee Mon Sep 17 00:00:00 2001 From: huhaosumail Date: Tue, 25 Jun 2024 21:01:03 +0800 Subject: [PATCH] =?UTF-8?q?Cffu=E6=96=B0=E5=A2=9Emulti-actions=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8F=8A=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 --- .../src/main/java/io/foldright/cffu/Cffu.java | 85 ++++++++++++++++++- .../java/io/foldright/cffu/CffuFactory.java | 45 +++++----- .../test/java/io/foldright/cffu/CffuTest.java | 49 +++++++++++ 3 files changed, 155 insertions(+), 24 deletions(-) diff --git a/cffu-core/src/main/java/io/foldright/cffu/Cffu.java b/cffu-core/src/main/java/io/foldright/cffu/Cffu.java index afab1116..11f82bec 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/Cffu.java +++ b/cffu-core/src/main/java/io/foldright/cffu/Cffu.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.Blocking; import org.jetbrains.annotations.Contract; +import java.util.List; import java.util.concurrent.*; import java.util.function.*; @@ -210,7 +211,89 @@ public Cffu thenRunAsync(Runnable action, Executor executor) { // region## Then-Multi-Actions(thenM*) Methods //////////////////////////////////////////////////////////// - // TODO: TO BE implemented!! + + /** + * 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 #mSupplyAsync(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 CompletableFuture#supplyAsync(Supplier) + */ + public Cffu> mSupplyFastFailAsync(Supplier... suppliers) { + return reset0(CompletableFutureUtils.mSupplyFastFailAsync(suppliers)); + } + + /** + * 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 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. + * + * @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 CompletableFuture#supplyAsync(Supplier) + */ + public Cffu> mSupplyMostSuccessAsync( + @Nullable T valueIfNotSuccess, long timeout, TimeUnit unit, Supplier... suppliers) { + return reset0(CompletableFutureUtils.mSupplyMostSuccessAsync(valueIfNotSuccess, timeout, unit, suppliers)); + } + + /** + * 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. + * + * @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 CompletableFuture#supplyAsync(Supplier) + */ + public Cffu> mSupplyAsync(Supplier... suppliers) { + return reset0(CompletableFutureUtils.mSupplyAsync(suppliers)); + } + + /** + * 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 CompletableFuture#runAsync(Runnable) + */ + public Cffu mRunFastFailAsync(Runnable... actions) { + return reset0(CompletableFutureUtils.mRunFastFailAsync(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. + * + * @param actions the actions to run before completing the returned CompletableFuture + * @return the new CompletableFuture + * @see CompletableFuture#runAsync(Runnable) + */ + public Cffu mRunAsync(Runnable... actions) { + return reset0(CompletableFutureUtils.mRunAsync(actions)); + } // endregion //////////////////////////////////////////////////////////// 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 3d8daaef..0ac6eb3e 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java @@ -167,7 +167,7 @@ public Cffu runAsync(Runnable action, Executor executor) { * @see #allResultsOfFastFail(CompletionStage[]) * @see CompletableFuture#supplyAsync(Supplier) */ - public Cffu> mSupplyFastFailAsync(Supplier... suppliers) { + public Cffu> mSupplyFastFailAsync(Supplier... suppliers) { return create(CompletableFutureUtils.mSupplyFastFailAsync(suppliers)); } @@ -223,7 +223,7 @@ public Cffu> mSupplyAsync(Supplier... suppliers) { * @see #allOfFastFail(CompletionStage[]) * @see CompletableFuture#runAsync(Runnable) */ - public Cffu mRunFastFailAsync(Runnable... actions) { + public Cffu mRunFastFailAsync(Runnable... actions) { return create(CompletableFutureUtils.mRunFastFailAsync(actions)); } @@ -237,7 +237,7 @@ public Cffu mRunFastFailAsync(Runnable... actions) { * @see #allOf(CompletionStage[]) * @see CompletableFuture#runAsync(Runnable) */ - public Cffu mRunAsync(Runnable... actions) { + public Cffu mRunAsync(Runnable... actions) { return create(CompletableFutureUtils.mRunAsync(actions)); } @@ -273,7 +273,7 @@ public Cffu> tupleMSupplyFastFailAsync( */ public Cffu> tupleMSupplyFastFailAsync( Executor executor, Supplier supplier1, Supplier supplier2) { - return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(executor,supplier1, supplier2)); + return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(executor, supplier1, supplier2)); } /** @@ -302,8 +302,8 @@ public Cffu> tupleMSupplyFastFailAsync( * @see #allResultsOfFastFail(CompletionStage[]) */ public Cffu> tupleMSupplyFastFailAsync( - Executor executor, Supplier supplier1, Supplier supplier2, Supplier supplier3) { - return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(executor,supplier1, supplier2, supplier3)); + Executor executor, Supplier supplier1, Supplier supplier2, Supplier supplier3) { + return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(executor, supplier1, supplier2, supplier3)); } /** @@ -333,9 +333,9 @@ public Cffu> tupleMSupplyFastFailAsync( * @see #allResultsOfFastFail(CompletionStage[]) */ public Cffu> tupleMSupplyFastFailAsync( - Executor executor,Supplier supplier1, Supplier supplier2, + Executor executor, Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4) { - return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(executor,supplier1, supplier2, supplier3, supplier4)); + return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(executor, supplier1, supplier2, supplier3, supplier4)); } /** @@ -367,7 +367,7 @@ public Cffu> tupleMSupplyFastFai public Cffu> tupleMSupplyFastFailAsync( Executor executor, Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4, Supplier supplier5) { - return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(executor,supplier1, supplier2, supplier3, supplier4, supplier5)); + return create(CompletableFutureUtils.tupleMSupplyFastFailAsync(executor, supplier1, supplier2, supplier3, supplier4, supplier5)); } @@ -397,7 +397,7 @@ public Cffu> tupleMSupplyMostSuccessAsync( */ public Cffu> tupleMSupplyMostSuccessAsync(Executor executor, long timeout, TimeUnit unit, Supplier supplier1, Supplier supplier2) { - return create(CompletableFutureUtils.tupleMSupplyMostSuccessAsync(executor,timeout, unit, supplier1, supplier2)); + return create(CompletableFutureUtils.tupleMSupplyMostSuccessAsync(executor, timeout, unit, supplier1, supplier2)); } /** @@ -413,7 +413,7 @@ public Cffu> tupleMSupplyMostSuccessAsync( long timeout, TimeUnit unit, Supplier supplier1, Supplier supplier2, Supplier supplier3) { return create(CompletableFutureUtils.tupleMSupplyMostSuccessAsync( - timeout, unit, supplier1, supplier2, supplier3)); + timeout, unit, supplier1, supplier2, supplier3)); } /** @@ -426,7 +426,7 @@ public Cffu> tupleMSupplyMostSuccessAsync( * @return the new Cffu */ public Cffu> tupleMSupplyMostSuccessAsync( - Executor executor,long timeout, TimeUnit unit, + Executor executor, long timeout, TimeUnit unit, Supplier supplier1, Supplier supplier2, Supplier supplier3) { return create(CompletableFutureUtils.tupleMSupplyMostSuccessAsync( executor, timeout, unit, supplier1, supplier2, supplier3)); @@ -445,7 +445,7 @@ public Cffu> tupleMSupplyMostSuccessAsyn long timeout, TimeUnit unit, Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4) { return create(CompletableFutureUtils.tupleMSupplyMostSuccessAsync( - timeout, unit, supplier1, supplier2, supplier3, supplier4)); + timeout, unit, supplier1, supplier2, supplier3, supplier4)); } /** @@ -458,7 +458,7 @@ public Cffu> tupleMSupplyMostSuccessAsyn * @return the new Cffu */ public Cffu> tupleMSupplyMostSuccessAsync( - Executor executor, long timeout, TimeUnit unit, Supplier supplier1, Supplier supplier2, + Executor executor, long timeout, TimeUnit unit, Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4) { return create(CompletableFutureUtils.tupleMSupplyMostSuccessAsync( executor, timeout, unit, supplier1, supplier2, supplier3, supplier4)); @@ -477,7 +477,7 @@ public Cffu> tupleMSupplyMostSuc long timeout, TimeUnit unit, Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4, Supplier supplier5) { return create(CompletableFutureUtils.tupleMSupplyMostSuccessAsync( - timeout, unit, supplier1, supplier2, supplier3, supplier4, supplier5)); + timeout, unit, supplier1, supplier2, supplier3, supplier4, supplier5)); } /** @@ -490,7 +490,7 @@ public Cffu> tupleMSupplyMostSuc * @return the new Cffu */ public Cffu> tupleMSupplyMostSuccessAsync( - Executor executor,long timeout, TimeUnit unit, Supplier supplier1, Supplier supplier2, + Executor executor, long timeout, TimeUnit unit, Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4, Supplier supplier5) { return create(CompletableFutureUtils.tupleMSupplyMostSuccessAsync( executor, timeout, unit, supplier1, supplier2, supplier3, supplier4, supplier5)); @@ -518,8 +518,8 @@ public Cffu> tupleMSupplyAsync( * @see #allResultsOf(CompletionStage[]) */ public Cffu> tupleMSupplyAsync( - Executor executor, Supplier supplier1, Supplier supplier2) { - return create(CompletableFutureUtils.tupleMSupplyAsync(executor,supplier1, supplier2)); + Executor executor, Supplier supplier1, Supplier supplier2) { + return create(CompletableFutureUtils.tupleMSupplyAsync(executor, supplier1, supplier2)); } /** @@ -544,8 +544,8 @@ public Cffu> tupleMSupplyAsync( * @see #allResultsOf(CompletionStage[]) */ public Cffu> tupleMSupplyAsync( - Executor executor, Supplier supplier1, Supplier supplier2, Supplier supplier3) { - return create(CompletableFutureUtils.tupleMSupplyAsync(executor,supplier1, supplier2, supplier3)); + Executor executor, Supplier supplier1, Supplier supplier2, Supplier supplier3) { + return create(CompletableFutureUtils.tupleMSupplyAsync(executor, supplier1, supplier2, supplier3)); } /** @@ -574,7 +574,7 @@ public Cffu> tupleMSupplyAsync( Executor executor, Supplier supplier1, Supplier supplier2, Supplier supplier3, Supplier supplier4) { - return create(CompletableFutureUtils.tupleMSupplyAsync(executor,supplier1, supplier2, supplier3, supplier4)); + return create(CompletableFutureUtils.tupleMSupplyAsync(executor, supplier1, supplier2, supplier3, supplier4)); } /** @@ -1181,8 +1181,7 @@ public static CompletableFuture[] cffuArrayUnwrap(Cffu... cfs) { */ @Contract(pure = true) public static Cffu[] cffuListToArray(List> cffuList) { - @SuppressWarnings("unchecked") - final Cffu[] a = new Cffu[cffuList.size()]; + @SuppressWarnings("unchecked") final Cffu[] a = new Cffu[cffuList.size()]; return cffuList.toArray(a); } diff --git a/cffu-core/src/test/java/io/foldright/cffu/CffuTest.java b/cffu-core/src/test/java/io/foldright/cffu/CffuTest.java index 6d4c641d..2642e78b 100644 --- a/cffu-core/src/test/java/io/foldright/cffu/CffuTest.java +++ b/cffu-core/src/test/java/io/foldright/cffu/CffuTest.java @@ -11,10 +11,13 @@ import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.condition.JRE; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.*; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import static io.foldright.test_utils.TestUtils.*; import static java.util.function.Function.identity; @@ -33,6 +36,52 @@ class CffuTest { private static CffuFactory forbidObtrudeMethodsCffuFactory; + //////////////////////////////////////////////////////////////////////////////// + //# multi-actions(M*) methods + //////////////////////////////////////////////////////////////////////////////// + + @Test + void test_mRun() throws Exception { + final Cffu completed = cffuFactory.completedFuture(n); + + final Runnable runnable = () -> sleep(100); + + final long tick = System.currentTimeMillis(); + @SuppressWarnings("unchecked") + Cffu[] cfs = new Cffu[]{ + completed.mRunAsync(runnable, runnable), + completed.mRunFastFailAsync(runnable, runnable) + }; + + assertTrue(System.currentTimeMillis() - tick < 50); + for (Cffu cf : cfs) { + assertNull(cf.get()); + } + } + + @Test + void test_mSupply() throws Exception { + final Cffu completed = cffuFactory.completedFuture(n); + final Supplier supplier = () -> { + sleep(100); + return n; + }; + + final long tick = System.currentTimeMillis(); + + @SuppressWarnings("unchecked") + Cffu>[] cfs = new Cffu[]{ + completed.mSupplyAsync(supplier, supplier), + completed.mSupplyFastFailAsync(supplier, supplier), + completed.mSupplyMostSuccessAsync(anotherN, 500, TimeUnit.MILLISECONDS, supplier, supplier) + }; + + assertTrue(System.currentTimeMillis() - tick < 50); + for (Cffu> cf : cfs) { + assertEquals(Arrays.asList(n, n), cf.get()); + } + } + @Test void test_thenTupleMApplyAsync() throws Exception { final Cffu completed = cffuFactory.completedFuture(n);