From edd8415844b85eb264056a9d887ba70730ef6da0 Mon Sep 17 00:00:00 2001 From: Jerry Lee Date: Sat, 18 May 2024 22:04:44 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20change=20`resultNow/exceptionNow/st?= =?UTF-8?q?ate`=20methods=20with=20more=20generic=20type(`Future`)=20in=20?= =?UTF-8?q?`CompletableFutureUtils`=20=F0=9F=A7=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/foldright/cffu/CffuState.java | 7 +- .../cffu/CompletableFutureUtils.java | 17 ++- .../cffu/CompletableFutureUtilsTest.java | 103 +++++++++++------- 3 files changed, 78 insertions(+), 49 deletions(-) diff --git a/cffu-core/src/main/java/io/foldright/cffu/CffuState.java b/cffu-core/src/main/java/io/foldright/cffu/CffuState.java index dae468df..8a030adc 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CffuState.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CffuState.java @@ -4,7 +4,6 @@ import org.jetbrains.annotations.Contract; import javax.annotation.ParametersAreNonnullByDefault; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import static java.util.Objects.requireNonNull; @@ -15,7 +14,7 @@ * * @author Jerry Lee (oldratlee at gmail dot com) * @see Future.State - * @see CompletableFutureUtils#state(CompletableFuture) + * @see CompletableFutureUtils#state(Future) * @see Cffu#cffuState() */ @ParametersAreNonnullByDefault @@ -35,7 +34,7 @@ public Future.State toFutureState() { * * @see Cffu#resultNow() * @see Future#resultNow() - * @see CompletableFutureUtils#resultNow(CompletableFuture) + * @see CompletableFutureUtils#resultNow(Future) */ SUCCESS { @Override @@ -48,7 +47,7 @@ public Future.State toFutureState() { * * @see Cffu#exceptionNow() * @see Future#exceptionNow() - * @see CompletableFutureUtils#exceptionNow(CompletableFuture) + * @see CompletableFutureUtils#exceptionNow(Future) */ FAILED { @Override 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 fc4ee004..64fa5410 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -1513,7 +1513,7 @@ public static T getSuccessNow(CompletableFuture cf, @Nullable T */ @Contract(pure = true) @Nullable - public static T resultNow(CompletableFuture cf) { + public static T resultNow(Future cf) { if (IS_JAVA19_PLUS) { return cf.resultNow(); } @@ -1550,7 +1550,7 @@ public static T resultNow(CompletableFuture cf) { * @see CompletableFuture#resultNow() */ @Contract(pure = true) - public static Throwable exceptionNow(CompletableFuture cf) { + public static Throwable exceptionNow(Future cf) { if (IS_JAVA19_PLUS) { return cf.exceptionNow(); } @@ -1588,7 +1588,7 @@ public static Throwable exceptionNow(CompletableFuture cf) { * @see Future.State */ @Contract(pure = true) - public static CffuState state(CompletableFuture cf) { + public static CffuState state(Future cf) { if (IS_JAVA19_PLUS) { return CffuState.toCffuState(cf.state()); } @@ -1598,6 +1598,17 @@ public static CffuState state(CompletableFuture cf) { if (!cf.isDone()) return CffuState.RUNNING; if (cf.isCancelled()) return CffuState.CANCELLED; + // simple path for CompletableFuture/Cffu + if (cf instanceof CompletableFuture) { + if (((CompletableFuture) cf).isCompletedExceptionally()) + return CffuState.FAILED; + else return CffuState.SUCCESS; + } else if (cf instanceof Cffu) { + if (((Cffu) cf).isCompletedExceptionally()) + return CffuState.FAILED; + else return CffuState.SUCCESS; + } + boolean interrupted = false; try { while (true) { 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 6d1cf883..8ec807aa 100644 --- a/cffu-core/src/test/java/io/foldright/cffu/CompletableFutureUtilsTest.java +++ b/cffu-core/src/test/java/io/foldright/cffu/CompletableFutureUtilsTest.java @@ -985,55 +985,78 @@ void test_exceptionallyCompose() throws Exception { @SuppressWarnings({"ResultOfMethodCallIgnored", "ThrowableNotThrown"}) void test_read() { final CompletableFuture completed = completedFuture(n); + final FutureTask completedTask = new FutureTask<>(() -> n); + completedTask.run(); + final CffuFactory cffuFactory = CffuFactory.builder(Executors.newCachedThreadPool()).build(); + final Cffu completedCffu = cffuFactory.completedFuture(n); assertEquals(n, join(completed, 1, TimeUnit.MILLISECONDS)); assertEquals(n, getSuccessNow(completed, anotherN)); assertEquals(n, getSuccessNow(completed, null)); assertEquals(n, resultNow(completed)); - try { - exceptionNow(completed); - fail(); - } catch (IllegalStateException expected) { - if (expected.getMessage() != null) assertEquals("Task completed with a result", expected.getMessage()); - } + assertEquals(n, resultNow(completedTask)); + assertEquals(n, resultNow(completedCffu)); + final String m1 = assertThrows(IllegalStateException.class, () -> + exceptionNow(completed) + ).getMessage(); + if (m1 != null) assertEquals("Task completed with a result", m1); + assertEquals("Task completed with a result", + assertThrows(IllegalStateException.class, () -> + exceptionNow(completedTask) + ).getMessage()); + final String m12 = assertThrows(IllegalStateException.class, () -> + exceptionNow(completedCffu) + ).getMessage(); + if (m12 != null) assertEquals("Task completed with a result", m12); assertSame(CffuState.SUCCESS, state(completed)); + assertSame(CffuState.SUCCESS, state(completedTask)); + assertSame(CffuState.SUCCESS, state(completedCffu)); //////////////////////////////////////// final CompletableFuture failed = failedFuture(rte); + final FutureTask failedTask = new FutureTask<>(() -> { + throw rte; + }); + failedTask.run(); + final Cffu failedCffu = cffuFactory.failedFuture(rte); - try { - join(failed, 1, TimeUnit.MILLISECONDS); - fail(); - } catch (CompletionException expected) { - assertSame(rte, expected.getCause()); - } + assertSame(rte, + assertThrows(CompletionException.class, () -> + join(failed, 1, TimeUnit.MILLISECONDS) + ).getCause()); assertEquals(anotherN, getSuccessNow(failed, anotherN)); assertNull(getSuccessNow(failed, null)); - try { - resultNow(failed); - fail(); - } catch (IllegalStateException expected) { - if (expected.getMessage() != null) assertEquals("Task completed with exception", expected.getMessage()); - } + final String m2 = assertThrows(IllegalStateException.class, () -> + resultNow(failed) + ).getMessage(); + if (m2 != null) assertEquals("Task completed with exception", m2); + assertNull(getSuccessNow(failed, null)); + final String m22 = assertThrows(IllegalStateException.class, () -> + resultNow(failedTask) + ).getMessage(); + final String m23 = assertThrows(IllegalStateException.class, () -> + resultNow(failedCffu) + ).getMessage(); + if (m22 != null) assertEquals("Task completed with exception", m22); assertSame(rte, exceptionNow(failed)); + assertSame(rte, exceptionNow(failedTask)); + assertSame(rte, exceptionNow(failedCffu)); assertSame(CffuState.FAILED, state(failed)); + assertSame(rte, exceptionNow(failedTask)); + assertSame(rte, exceptionNow(failedCffu)); //////////////////////////////////////// CompletableFuture cancelled = createCancelledFuture(); - try { - resultNow(cancelled); - fail(); - } catch (IllegalStateException expected) { - if (expected.getMessage() != null) assertEquals("Task was cancelled", expected.getMessage()); - } - try { - exceptionNow(cancelled); - fail(); - } catch (IllegalStateException expected) { - if (expected.getMessage() != null) assertEquals("Task was cancelled", expected.getMessage()); - } + final String m3 = assertThrows(IllegalStateException.class, () -> + resultNow(cancelled) + ).getMessage(); + if (m3 != null) assertEquals("Task was cancelled", m3); + final String m4 = assertThrows(IllegalStateException.class, () -> + exceptionNow(cancelled) + ).getMessage(); + if (m4 != null) assertEquals("Task was cancelled", m4); assertSame(CffuState.CANCELLED, state(cancelled)); //////////////////////////////////////// @@ -1048,18 +1071,14 @@ void test_read() { } assertEquals(anotherN, getSuccessNow(incomplete, anotherN)); assertNull(getSuccessNow(incomplete, null)); - try { - resultNow(incomplete); - fail(); - } catch (IllegalStateException expected) { - if (expected.getMessage() != null) assertEquals("Task has not completed", expected.getMessage()); - } - try { - exceptionNow(incomplete); - fail(); - } catch (IllegalStateException expected) { - if (expected.getMessage() != null) assertEquals("Task has not completed", expected.getMessage()); - } + final String m5 = assertThrows(IllegalStateException.class, () -> + resultNow(incomplete) + ).getMessage(); + if (m5 != null) assertEquals("Task has not completed", m5); + final String m6 = assertThrows(IllegalStateException.class, () -> + exceptionNow(incomplete) + ).getMessage(); + if (m6 != null) assertEquals("Task has not completed", m6); assertSame(CffuState.RUNNING, state(incomplete)); // Incomplete Future -> join before timeout