Skip to content

Commit

Permalink
refactor: change resultNow/exceptionNow/state methods with more gen…
Browse files Browse the repository at this point in the history
…eric type(`Future`) in `CompletableFutureUtils` 🧬
  • Loading branch information
oldratlee committed May 24, 2024
1 parent 757b61d commit 5a5ad44
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 49 deletions.
7 changes: 3 additions & 4 deletions cffu-core/src/main/java/io/foldright/cffu/CffuState.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -35,7 +34,7 @@ public Future.State toFutureState() {
*
* @see Cffu#resultNow()
* @see Future#resultNow()
* @see CompletableFutureUtils#resultNow(CompletableFuture)
* @see CompletableFutureUtils#resultNow(Future)
*/
SUCCESS {
@Override
Expand All @@ -48,7 +47,7 @@ public Future.State toFutureState() {
*
* @see Cffu#exceptionNow()
* @see Future#exceptionNow()
* @see CompletableFutureUtils#exceptionNow(CompletableFuture)
* @see CompletableFutureUtils#exceptionNow(Future)
*/
FAILED {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1513,7 +1513,7 @@ public static <T> T getSuccessNow(CompletableFuture<? extends T> cf, @Nullable T
*/
@Contract(pure = true)
@Nullable
public static <T> T resultNow(CompletableFuture<T> cf) {
public static <T> T resultNow(Future<T> cf) {
if (IS_JAVA19_PLUS) {
return cf.resultNow();
}
Expand Down Expand Up @@ -1550,7 +1550,7 @@ public static <T> T resultNow(CompletableFuture<T> 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();
}
Expand Down Expand Up @@ -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());
}
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -985,55 +985,78 @@ void test_exceptionallyCompose() throws Exception {
@SuppressWarnings({"ResultOfMethodCallIgnored", "ThrowableNotThrown"})
void test_read() {
final CompletableFuture<Integer> completed = completedFuture(n);
final FutureTask<Integer> completedTask = new FutureTask<>(() -> n);
completedTask.run();
final CffuFactory cffuFactory = CffuFactory.builder(Executors.newCachedThreadPool()).build();
final Cffu<Integer> 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<Object> failed = failedFuture(rte);
final FutureTask<Integer> failedTask = new FutureTask<>(() -> {
throw rte;
});
failedTask.run();
final Cffu<Object> 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<Object> 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));

////////////////////////////////////////
Expand All @@ -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
Expand Down

0 comments on commit 5a5ad44

Please sign in to comment.