Joins a stream of futures, returning a single joint future. Accumulation or reduction of results is intentionally not
supported, so all futures must be of (or converted to) type
Void (see below).
The stream is consumed as fast as possible without the number of incomplete futures exceeding
concurrencyLimit. The stream consumer is executed by the given
ExecutorService.
Exceptional completion of futures
- When one or more of the futures inside the stream complete exceptionally, so does the joint future. After that,
one more future will be consumed from the stream, but the joint future will not wait for it to complete.
- The
Throwable result of the joint future will be that of the first future to complete exceptionally;
others will be lost.
- As with other futures, the throwable result of a computation will be wrapped inside an
ExecutionException, e.g. when invoking get(). Note that this happens regardless of the
type of throwable (checked exception, runtime exception, error).
Exceptions thrown by the original stream
If the original stream throws an exception instead of producing a future, the joint future will behave the same way
as with exceptional completion of futures: the exception will be wrapped inside an
ExecutionException, e.g.
when invoking
get().
Usage examples
Stream<CompletableFuture<Void>> completables;
CompletableFuture<Void> jointFuture = FutureStreamJoiner.completable().join(completables, concurrencyLimit, executorService);
Stream<ListenableFuture<Void>> listenables;
ListenableFuture<Void> jointFuture = FutureStreamJoiner.listenable().join(listenables, concurrencyLimit, executorService);
As this class can't handle a future's result by design, it only accepts futures without result. If the futures in
the stream
do contain results, the intention to discard those results can be documented by using
Futures.toVoidResult(CompletableFuture) or
Futures.toVoidResult(ListenableFuture):
Stream<CompletableFuture<MyPojo>> resultFutures;
Stream<CompletableFuture<Void>> voidFutures = resultFutures.map(Futures::toVoidResult);
CompletableFuture<Void> jointFuture = FutureStreamJoiner.completable().join(voidFutures, concurrencyLimit, executorService);
Stream<ListenableFuture<MyPojo>> resultFutures;
Stream<ListenableFuture<Void>> voidFutures = resultFutures.map(Futures::toVoidResult);
CompletableFuture<Void> jointFuture = FutureStreamJoiner.listenable().join(voidFutures, concurrencyLimit, executorService);