CompletedFuture - Aggregate future for quick exit

I use an assistant CompletableFuture.allOf(...)to create aggregate futures that will only be “executed” when their composite futures are marked as completed, for example:

CompletableFuture<?> future1 = new CompletableFuture<>();
CompletableFuture<?> future2 = new CompletableFuture<>();
CompletableFuture<?> future3 = new CompletableFuture<>();

CompletableFuture<?> future = CompletableFuture.allOf(future1, future2, future3);

I would like to slightly change this functionality, where the aggregate future will be complete when:

  • All futures completed successfully OR
  • Any one future failed

In the latter case, the aggregate future should end (exclusively) immediately, and there is no need to wait for the completion of other futures, i.e. with an error.

To illustrate this, unlike CompletableFuture.allOf(...), consider the following:

// First future completed, gotta wait for the rest of them...
future1.complete(null);
System.out.println("Future1 Complete, aggregate status: " + future.isDone());

// Second feature was erroneous! I'd like the aggregate to now be completed with failure
future2.completeExceptionally(new Exception());
System.out.println("Future2 Complete, aggregate status: " + future.isDone());

// Finally complete the third future, that will mark the aggregate as done
future3.complete(null);
System.out.println("Future3 Complete, aggregate status: " + future.isDone());

Using allOf(...), this code gives:

Future1 Complete, aggregate status: false
Future2 Complete, aggregate status: false
Future3 Complete, aggregate status: true

"" , Feature2 , , .


utils Java, , ... .

CompletableFuture.allOf(...), , . , , ?

+4
2

, CompletableFuture.allOf(...), , thenCompose(...) :

CompletableFuture<?> future = future1.thenCompose((f) -> future2).thenCompose((f) -> future3);

:

Future1 Complete, aggregate status: false
Future2 Complete, aggregate status: true
Future3 Complete, aggregate status: true

, :

private static CompletableFuture<?> composed(CompletableFuture<?> ... futures) {

    // Complete when ALL the underlying futures are completed
    CompletableFuture<?> allComplete = CompletableFuture.allOf(futures);

    // Complete when ANY of the underlying futures are exceptional
    CompletableFuture<?> anyException = new CompletableFuture<>();
    for (CompletableFuture<?> completableFuture : futures) {
        completableFuture.exceptionally((t) -> {
            anyException.completeExceptionally(t);
            return null;
        });
    }

    // Complete when either of the above are satisfied
    return CompletableFuture.anyOf(allComplete, anyException);
}

:

CompletableFuture<?> future = composed(future1, future2, future3);
+2

, , allOf, anyOf, anyOf.

0

Source: https://habr.com/ru/post/1616393/


All Articles