From 87afc5d9fae9508d7285690866aadd1ae43c018d Mon Sep 17 00:00:00 2001 From: Jerry Lee Date: Tue, 30 Apr 2024 00:56:13 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20improve=20generic=20type=20declarat?= =?UTF-8?q?ion=20=F0=9F=A7=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cffu/CompletableFutureUtils.java | 74 +++++++++---------- .../foldright/cffu/DelayExecutionHelpers.java | 16 ++-- .../cffu/CompletableFutureUtilsTest.java | 18 ++++- 3 files changed, 61 insertions(+), 47 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 fc43455f..27463211 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -886,7 +886,7 @@ public static CompletableFuture acceptEitherSuccessAsync( * @see CompletionStage#applyToEither(CompletionStage, Function) */ public static CompletableFuture applyToEitherSuccess( - CompletionStage cf1, CompletionStage cf2, Function fn) { + CompletionStage cf1, CompletionStage cf2, Function fn) { final CompletionStage[] css = requireCfsAndEleNonNull(cf1, cf2); requireNonNull(fn, "fn is null"); @@ -907,7 +907,7 @@ public static CompletableFuture applyToEitherSuccess( * @see CompletionStage#applyToEitherAsync(CompletionStage, Function) */ public static CompletableFuture applyToEitherSuccessAsync( - CompletionStage cf1, CompletionStage cf2, Function fn) { + CompletionStage cf1, CompletionStage cf2, Function fn) { final CompletionStage[] css = requireCfsAndEleNonNull(cf1, cf2); requireNonNull(fn, "fn is null"); @@ -929,7 +929,7 @@ public static CompletableFuture applyToEitherSuccessAsync( */ public static CompletableFuture applyToEitherSuccessAsync( CompletionStage cf1, CompletionStage cf2, - Function fn, Executor executor) { + Function fn, Executor executor) { final CompletionStage[] css = requireCfsAndEleNonNull(cf1, cf2); requireNonNull(fn, "fn is null"); requireNonNull(executor, "executor is null"); @@ -1029,6 +1029,7 @@ public static CompletableFuture failedFuture(Throwable ex) { if (IS_JAVA9_PLUS) { return CompletableFuture.failedFuture(ex); } + requireNonNull(ex, "ex is null"); final CompletableFuture cf = new CompletableFuture<>(); cf.completeExceptionally(ex); return cf; @@ -1163,16 +1164,16 @@ public static CompletableFuture exceptionallyAsync( * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter * @return given CompletableFuture */ - public static CompletableFuture orTimeout(CompletableFuture cf, long timeout, TimeUnit unit) { + public static > C orTimeout(C cf, long timeout, TimeUnit unit) { if (IS_JAVA9_PLUS) { - return cf.orTimeout(timeout, unit); - } - - requireNonNull(unit, "unit is null"); - // below code is copied from CompletableFuture#orTimeout with small adoption - if (!cf.isDone()) { - ScheduledFuture f = Delayer.delayToTimoutCf(cf, timeout, unit); - cf.whenComplete(new FutureCanceller(f)); + cf.orTimeout(timeout, unit); + } else { + requireNonNull(unit, "unit is null"); + // below code is copied from CompletableFuture#orTimeout with small adoption + if (!cf.isDone()) { + ScheduledFuture f = Delayer.delayToTimoutCf(cf, timeout, unit); + cf.whenComplete(new FutureCanceller(f)); + } } return cf; } @@ -1185,17 +1186,17 @@ public static CompletableFuture orTimeout(CompletableFuture cf, long t * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter * @return given CompletableFuture */ - public static CompletableFuture completeOnTimeout( - CompletableFuture cf, @Nullable T value, long timeout, TimeUnit unit) { + public static > C completeOnTimeout( + C cf, @Nullable T value, long timeout, TimeUnit unit) { if (IS_JAVA9_PLUS) { - return cf.completeOnTimeout(value, timeout, unit); - } - - requireNonNull(unit, "unit is null"); - // below code is copied from CompletableFuture#completeOnTimeout with small adoption - if (!cf.isDone()) { - ScheduledFuture f = Delayer.delayToCompleteCf(cf, value, timeout, unit); - cf.whenComplete(new FutureCanceller(f)); + cf.completeOnTimeout(value, timeout, unit); + } else { + requireNonNull(unit, "unit is null"); + // below code is copied from CompletableFuture#completeOnTimeout with small adoption + if (!cf.isDone()) { + ScheduledFuture f = Delayer.delayToCompleteCf(cf, value, timeout, unit); + cf.whenComplete(new FutureCanceller(f)); + } } return cf; } @@ -1215,7 +1216,6 @@ public static CompletableFuture exceptionallyCompose( if (IS_JAVA12_PLUS) { return cf.exceptionallyCompose(fn); } - requireNonNull(fn, "fn is null"); // below code is copied from CompletionStage.exceptionallyCompose return cf.handle((r, ex) -> (ex == null) ? cf : fn.apply(ex)).thenCompose(identity()); @@ -1249,7 +1249,6 @@ public static CompletableFuture exceptionallyComposeAsync( if (IS_JAVA12_PLUS) { return cf.exceptionallyComposeAsync(fn, executor); } - requireNonNull(fn, "fn is null"); requireNonNull(executor, "executor is null"); // below code is copied from CompletionStage.exceptionallyComposeAsync @@ -1294,7 +1293,6 @@ public static CompletableFuture exceptionallyComposeAsync( @Nullable public static T join(CompletableFuture cf, long timeout, TimeUnit unit) { if (cf.isDone()) return cf.join(); - return orTimeout(copy(cf), timeout, unit).join(); } @@ -1313,7 +1311,7 @@ public static T join(CompletableFuture cf, long timeout, TimeUnit unit) { */ @Contract(pure = true) @Nullable - public static T resultNow(CompletableFuture cf) { + public static T resultNow(CompletableFuture cf) { if (IS_JAVA19_PLUS) { return cf.resultNow(); } @@ -1350,7 +1348,7 @@ public static T resultNow(CompletableFuture cf) { * @see CompletableFuture#resultNow() */ @Contract(pure = true) - public static Throwable exceptionNow(CompletableFuture cf) { + public static Throwable exceptionNow(CompletableFuture cf) { if (IS_JAVA19_PLUS) { return cf.exceptionNow(); } @@ -1388,7 +1386,7 @@ public static Throwable exceptionNow(CompletableFuture cf) { * @see Future.State */ @Contract(pure = true) - public static CffuState state(CompletableFuture cf) { + public static CffuState state(CompletableFuture cf) { if (IS_JAVA19_PLUS) { return CffuState.toCffuState(cf.state()); } @@ -1424,7 +1422,7 @@ public static CffuState state(CompletableFuture cf) { * @param supplier a function returning the value to be used to complete given CompletableFuture * @return given CompletableFuture */ - public static CompletableFuture completeAsync(CompletableFuture cf, Supplier supplier) { + public static > C completeAsync(C cf, Supplier supplier) { return completeAsync(cf, supplier, AsyncPoolHolder.ASYNC_POOL); } @@ -1436,15 +1434,16 @@ public static CompletableFuture completeAsync(CompletableFuture cf, Su * @param executor the executor to use for asynchronous execution * @return given CompletableFuture */ - public static CompletableFuture completeAsync( - CompletableFuture cf, Supplier supplier, Executor executor) { + public static > C completeAsync( + C cf, Supplier supplier, Executor executor) { if (IS_JAVA9_PLUS) { - return cf.completeAsync(supplier, executor); + cf.completeAsync(supplier, executor); + } else { + requireNonNull(supplier, "supplier is null"); + requireNonNull(executor, "executor is null"); + // below code is copied from CompletableFuture#completeAsync with small adoption + executor.execute(new CfCompleterBySupplier<>(cf, supplier)); } - requireNonNull(supplier, "supplier is null"); - requireNonNull(executor, "executor is null"); - // below code is copied from CompletableFuture#completeAsync with small adoption - executor.execute(new CfCompleterBySupplier<>(cf, supplier)); return cf; } @@ -1490,11 +1489,10 @@ public static CompletableFuture copy(CompletableFuture cf) { /** * Returns a new incomplete CompletableFuture of the type to be returned by a CompletionStage method. * - * @param the type of the value * @return a new CompletableFuture */ @Contract(pure = true) - public static CompletableFuture newIncompleteFuture(CompletableFuture cf) { + public static CompletableFuture newIncompleteFuture(CompletableFuture cf) { if (IS_JAVA9_PLUS) { return cf.newIncompleteFuture(); } diff --git a/cffu-core/src/main/java/io/foldright/cffu/DelayExecutionHelpers.java b/cffu-core/src/main/java/io/foldright/cffu/DelayExecutionHelpers.java index 65de22da..d5116ea9 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/DelayExecutionHelpers.java +++ b/cffu-core/src/main/java/io/foldright/cffu/DelayExecutionHelpers.java @@ -46,7 +46,8 @@ public static ScheduledFuture delayToTimoutCf(CompletableFuture cf, long d * @return a Future can be used to cancel the delayed task(complete CF) * @see FutureCanceller */ - public static ScheduledFuture delayToCompleteCf(CompletableFuture cf, T value, long delay, TimeUnit unit) { + public static ScheduledFuture delayToCompleteCf( + CompletableFuture cf, T value, long delay, TimeUnit unit) { return delay(new CfCompleter<>(cf, value), delay, unit); } @@ -128,11 +129,10 @@ public void run() { * Action to complete cf */ final class CfCompleter implements Runnable { - private final CompletableFuture cf; + private final CompletableFuture cf; private final T value; - @SuppressWarnings("BoundedWildcard") - CfCompleter(CompletableFuture cf, T value) { + CfCompleter(CompletableFuture cf, T value) { this.cf = cf; this.value = value; } @@ -171,10 +171,10 @@ public void accept(Object ignore, Throwable ex) { @SuppressFBWarnings("SE_BAD_FIELD") final class CfCompleterBySupplier extends ForkJoinTask implements Runnable, CompletableFuture.AsynchronousCompletionTask { - CompletableFuture dep; - Supplier fn; + private CompletableFuture dep; + private Supplier fn; - CfCompleterBySupplier(CompletableFuture dep, Supplier fn) { + CfCompleterBySupplier(CompletableFuture dep, Supplier fn) { this.dep = dep; this.fn = fn; } @@ -196,7 +196,7 @@ public boolean exec() { @Override public void run() { - CompletableFuture d; + CompletableFuture d; Supplier f; if ((d = dep) != null && (f = fn) != null) { dep = null; 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 3a1b5e90..9c047ab7 100644 --- a/cffu-core/src/test/java/io/foldright/cffu/CompletableFutureUtilsTest.java +++ b/cffu-core/src/test/java/io/foldright/cffu/CompletableFutureUtilsTest.java @@ -15,7 +15,6 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiConsumer; import java.util.function.Consumer; -import java.util.function.Function; import static io.foldright.cffu.CompletableFutureUtils.*; import static io.foldright.test_utils.TestUtils.*; @@ -1005,6 +1004,23 @@ void test_executor() { assertSame(e, screenExecutor(e)); } + //////////////////////////////////////////////////////////////////////////////// + //# check type parameter declaration, Variance(covariance/contravariance) + //////////////////////////////////////////////////////////////////////////////// + + @Test + @SuppressWarnings("UnnecessaryLocalVariable") + void checkTypeParameterDeclaration() throws Exception { + final CompletableFuture f = completedFuture(42); + + final CompletableFuture fe = f; + CompletableFutureUtils.peek(fe, (v, ex) -> { + }).get(); + + final CompletableFuture fs = f; + CompletableFutureUtils.completeAsync(fs, () -> 0).complete(1); + } + //////////////////////////////////////////////////////////////////////////////// //# test helper fields ////////////////////////////////////////////////////////////////////////////////