Reputation: 171
Below code snippet to consolidate completable future . the problem with below is some of my futures are completing exceptionally so on a whole my result is completeling exceptionally .
from the java doc I understand allof returns exception when any future throws exception "Returns a new CompletableFuture that is completed when all of the given CompletableFutures complete. If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture also does so, with a CompletionException holding this exception as its cause."
but I dont see any other api that helps me to get future when all are done
can some one help me or any clues How Can I skip futures which are completing exceptionally . In other words I want to get futures which are completed without exceptions .
CompletableFuture<List<Pair<ExtensionVO, GetObjectResponse>>> result =
CompletableFuture.allOf(
completableFutures.toArray(new CompletableFuture<?>[completableFutures.size()]))
.thenApply(
v ->
completableFutures
.stream()
.map(CompletableFuture::join)
.filter(Objects::nonNull)
.collect(Collectors.toList()));
Upvotes: 0
Views: 1638
Reputation: 298499
First, you have to use handle
to chain a function which can produce a result even in the exceptional case, then, use .filter(f -> !f.isCompletedExceptionally())
to skip exceptionally completed futures before calling join()
:
CompletableFuture<List<Pair<ExtensionVO, GetObjectResponse>>> result =
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture<?>[0]))
.handle((voidResult,throwable) ->
completableFutures
.stream()
.filter(f -> !f.isCompletedExceptionally())
.map(CompletableFuture::join)
.filter(Objects::nonNull)
.collect(Collectors.toList()));
In principle, you could use the throwable
to determine whether an exception happened, to perform the isCompletedExceptionally()
check only when necessary:
CompletableFuture<List<Pair<ExtensionVO, GetObjectResponse>>> result =
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture<?>[0]))
.handle((voidResult, throwable) ->
(throwable == null?
completableFutures.stream():
completableFutures.stream().filter(f -> !f.isCompletedExceptionally()))
.map(CompletableFuture::join)
.filter(Objects::nonNull)
.collect(Collectors.toList()));
but this may only pay off for really large lists, if ever.
Upvotes: 1