Skip to content

Commit

Permalink
refactor: reorder Cffu.cffuUnwrap and revise its javadoc; add QA an…
Browse files Browse the repository at this point in the history
…notations to `CompletableFutureUtils.unwrapCfException`; uniform local var name
  • Loading branch information
oldratlee committed Jul 27, 2024
1 parent 4f20735 commit 48ba01c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 39 deletions.
35 changes: 18 additions & 17 deletions cffu-core/src/main/java/io/foldright/cffu/Cffu.java
Original file line number Diff line number Diff line change
Expand Up @@ -2844,23 +2844,6 @@ public boolean isMinimalStage() {
// region# Inspection Methods
////////////////////////////////////////////////////////////////////////////////

/**
* Returns the underlying CompletableFuture.
* <p>
* {@link CffuFactory#toCffu(CompletionStage)} is inverse operation to this method.
* {@link CffuFactory#cffuArrayUnwrap(Cffu[])} is the batch operation to this method.
*
* @return the underlying CompletableFuture
* @see CffuFactory#toCffu(CompletionStage)
* @see CffuFactory#cffuArrayUnwrap(Cffu[])
* @see #toCompletableFuture()
*/
@Contract(pure = true)
@SuppressFBWarnings("EI_EXPOSE_REP")
public CompletableFuture<T> cffuUnwrap() {
return cf;
}

/**
* Returns the estimated number of Cffus whose completions are awaiting completion of this Cffu.
* This method is designed for use in monitoring system state, not for synchronization control.
Expand All @@ -2880,6 +2863,7 @@ public int getNumberOfDependents() {
// - dangerous
// - obtrudeValue(value)
// - obtrudeException(ex)
// - cffuUnwrap()
// - for API compatibility of CompletableFuture
// - newIncompleteFuture()
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2916,6 +2900,23 @@ public void obtrudeException(Throwable ex) {
cf.obtrudeException(ex);
}

/**
* Returns the underlying CompletableFuture.
* In general, you should NEVER use this method, use {@link #toCompletableFuture()} instead.
* <p>
* {@link CffuFactory#cffuArrayUnwrap(Cffu[])} is the batch operation to this method.
*
* @return the underlying CompletableFuture
* @see #toCompletableFuture()
* @see CffuFactory#cffuArrayUnwrap(Cffu[])
* @see #toCompletableFuture()
*/
@Contract(pure = true)
@SuppressFBWarnings("EI_EXPOSE_REP")
public CompletableFuture<T> cffuUnwrap() {
return cf;
}

/**
* Returns a new incomplete Cffu with CompletableFuture of the type to be returned by a CompletionStage method.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3575,7 +3575,8 @@ public static CompletableFuture<Void> runAfterEitherSuccessAsync(
C catching(C cfThis, Class<X> exceptionType, Function<? super X, ? extends T> fallback) {
requireNonNull(cfThis, "cfThis is null");
requireNonNull(fallback, "fallback is null");
return (C) cfThis.handle((r, ex) -> (ex == null || !exceptionType.isAssignableFrom(ex.getClass()))

return (C) cfThis.handle((v, ex) -> (ex == null || !exceptionType.isAssignableFrom(ex.getClass()))
? cfThis : completedFuture(fallback.apply((X) ex))
).thenCompose(x -> x);
}
Expand Down Expand Up @@ -3617,8 +3618,9 @@ C catchingAsync(C cfThis, Class<X> exceptionType, Function<? super X, ? extends
requireNonNull(cfThis, "cfThis is null");
requireNonNull(fallback, "fallback is null");
requireNonNull(executor, "executor is null");
return (C) cfThis.handle((r, ex) -> (ex == null || !exceptionType.isAssignableFrom(ex.getClass()))
? cfThis : cfThis.<T>handleAsync((r1, ex1) -> fallback.apply((X) ex1), executor)

return (C) cfThis.handle((v, ex) -> (ex == null || !exceptionType.isAssignableFrom(ex.getClass()))
? cfThis : cfThis.<T>handleAsync((v1, ex1) -> fallback.apply((X) ex1), executor)
).thenCompose(x -> x);
}

Expand Down Expand Up @@ -3657,8 +3659,8 @@ C exceptionallyAsync(C cfThis, Function<Throwable, ? extends T> fn, Executor exe
return (C) cfThis.exceptionallyAsync(fn, executor);
}
// below code is copied from CompletionStage#exceptionallyAsync
return (C) cfThis.handle((r, ex) -> (ex == null) ? cfThis :
cfThis.<T>handleAsync((r1, ex1) -> fn.apply(ex1), executor)
return (C) cfThis.handle((v, ex) -> (ex == null) ? cfThis :
cfThis.<T>handleAsync((v1, ex1) -> fn.apply(ex1), executor)
).thenCompose(x -> x);
}

Expand Down Expand Up @@ -3871,7 +3873,7 @@ private static void completeCf(CompletableFuture<Object> cf, Object value, @Null
C catchingCompose(C cfThis, Class<X> exceptionType, Function<? super X, ? extends CompletionStage<T>> fallback) {
requireNonNull(cfThis, "cfThis is null");
requireNonNull(fallback, "fallback is null");
return (C) cfThis.handle((r, ex) -> (ex == null || !exceptionType.isAssignableFrom(ex.getClass()))
return (C) cfThis.handle((v, ex) -> (ex == null || !exceptionType.isAssignableFrom(ex.getClass()))
? cfThis : fallback.apply((X) ex)
).thenCompose(x -> x);
}
Expand Down Expand Up @@ -3913,8 +3915,8 @@ public static <T, X extends Throwable, C extends CompletionStage<? super T>> C c
requireNonNull(cfThis, "cfThis is null");
requireNonNull(fallback, "fallback is null");
requireNonNull(executor, "executor is null");
return (C) cfThis.handle((r, ex) -> (ex == null || !exceptionType.isAssignableFrom(ex.getClass()))
? cfThis : cfThis.handleAsync((r1, ex1) -> fallback.apply((X) ex1), executor).thenCompose(x -> x)
return (C) cfThis.handle((v, ex) -> (ex == null || !exceptionType.isAssignableFrom(ex.getClass()))
? cfThis : cfThis.handleAsync((v1, ex1) -> fallback.apply((X) ex1), executor).thenCompose(x -> x)
).thenCompose(x -> x);
}

Expand All @@ -3935,7 +3937,7 @@ C exceptionallyCompose(C cfThis, Function<Throwable, ? extends CompletionStage<T
return (C) cfThis.exceptionallyCompose((Function) fn);
}
// below code is copied from CompletionStage.exceptionallyCompose
return (C) cfThis.handle((r, ex) -> (ex == null) ? cfThis : fn.apply(ex)).thenCompose(x -> x);
return (C) cfThis.handle((v, ex) -> (ex == null) ? cfThis : fn.apply(ex)).thenCompose(x -> x);
}

/**
Expand Down Expand Up @@ -3971,8 +3973,8 @@ C exceptionallyComposeAsync(C cfThis, Function<Throwable, ? extends CompletionSt
return (C) cfThis.exceptionallyComposeAsync((Function) fn, executor);
}
// below code is copied from CompletionStage.exceptionallyComposeAsync
return (C) cfThis.handle((r, ex) -> (ex == null) ? cfThis :
cfThis.handleAsync((r1, ex1) -> fn.apply(ex1), executor).thenCompose(x -> x)
return (C) cfThis.handle((v, ex) -> (ex == null) ? cfThis :
cfThis.handleAsync((v1, ex1) -> fn.apply(ex1), executor).thenCompose(x -> x)
).thenCompose(x -> x);
}

Expand Down Expand Up @@ -4454,7 +4456,8 @@ public static <T> CompletableFuture<T>[] completableFutureListToArray(List<Compl
* A convenient util method for unwrapping CF exception
* ({@link CompletionException}/{@link ExecutionException}) to the biz exception.
*/
public static Throwable unwrapCfException(Throwable ex) {
@Contract(value = "null -> null; !null -> !null", pure = true)
public static @Nullable Throwable unwrapCfException(@Nullable Throwable ex) {
if (!(ex instanceof CompletionException) && !(ex instanceof ExecutionException)) {
return ex;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1488,23 +1488,23 @@ void test_safeBehavior_orTimeout() {
final List<Integer> results = IntStream.range(0, 10).boxed().collect(Collectors.toList());

assertEquals(results, results.stream().map(i ->
orTimeout(createIncompleteFuture(), 100, TimeUnit.MILLISECONDS).handle((r1, ex1) -> {
assertInstanceOf(TimeoutException.class, ex1);
orTimeout(createIncompleteFuture(), 100, TimeUnit.MILLISECONDS).handle((v, ex) -> {
assertInstanceOf(TimeoutException.class, ex);
assertTrue(Delayer.atCfDelayerThread());
return i;
})
).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList()));

assertEquals(results, results.stream().map(i ->
cffuOrTimeout(createIncompleteFuture(), 100, TimeUnit.MILLISECONDS).handle((r, ex) -> {
cffuOrTimeout(createIncompleteFuture(), 100, TimeUnit.MILLISECONDS).handle((v, ex) -> {
assertInstanceOf(TimeoutException.class, ex);
assertFalse(Delayer.atCfDelayerThread());
assertNotSame(testThread, currentThread());
return i;
})
).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList()));
assertEquals(results, results.stream().map(i ->
cffuOrTimeout(createIncompleteFuture(), executorService, 100, TimeUnit.MILLISECONDS).handle((r, ex) -> {
cffuOrTimeout(createIncompleteFuture(), executorService, 100, TimeUnit.MILLISECONDS).handle((v, ex) -> {
assertInstanceOf(TimeoutException.class, ex);
assertFalse(Delayer.atCfDelayerThread());
assertTrue(TestThreadPoolManager.isRunInExecutor(executorService));
Expand All @@ -1519,27 +1519,27 @@ void test_safeBehavior_completeOnTimeout() {
final List<Integer> results = IntStream.range(0, 10).boxed().collect(Collectors.toList());

assertEquals(results, results.stream().map(i ->
completeOnTimeout(createIncompleteFuture(), i, 100, TimeUnit.MILLISECONDS).handle((r, ex) -> {
completeOnTimeout(createIncompleteFuture(), i, 100, TimeUnit.MILLISECONDS).handle((v, ex) -> {
assertNull(ex);
assertTrue(Delayer.atCfDelayerThread());
return r;
return v;
})
).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList()));

assertEquals(results, results.stream().map(i ->
cffuCompleteOnTimeout(createIncompleteFuture(), i, 100, TimeUnit.MILLISECONDS).handle((r, ex) -> {
cffuCompleteOnTimeout(createIncompleteFuture(), i, 100, TimeUnit.MILLISECONDS).handle((v, ex) -> {
assertNull(ex);
assertFalse(Delayer.atCfDelayerThread());
assertNotSame(testThread, currentThread());
return r;
return v;
})
).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList()));
assertEquals(results, results.stream().map(i ->
cffuCompleteOnTimeout(createIncompleteFuture(), i, executorService, 100, TimeUnit.MILLISECONDS).handle((r, ex) -> {
cffuCompleteOnTimeout(createIncompleteFuture(), i, executorService, 100, TimeUnit.MILLISECONDS).handle((v, ex) -> {
assertNull(ex);
assertFalse(Delayer.atCfDelayerThread());
assertTrue(TestThreadPoolManager.isRunInExecutor(executorService));
return r;
return v;
})
).collect(Collectors.toList()).stream().map(CompletableFuture::join).collect(Collectors.toList()));
}
Expand Down

0 comments on commit 48ba01c

Please sign in to comment.