I'm working on a problem where I have a List<ListenableFuture<T>>
. I would like to aggregate the results of all of these futures into a List<T>
with a timeout. The naive approach would be something like:
List<T> blockForResponses(List<ListenableFuture<T>> futures, long timeoutMillis) {
return futures.stream()
.map(future -> future.get(timeoutMillis,TimeUnit.MILLISECONDS)
.collect(Collectors.toList());
}
This doesn't work because it waits for the timeout for each future and I want that to be the timeout for the entire list. Manually keeping track of how much time has passed also doesn't work because if the first one times out, there won't be any time left to try the others.
The solution I'm looking for would enforce a timeout on all of the futures and return when the timeout had elapsed or all of the futures in the list were complete. Then I could inspect each future in the list myself to aggregate the results and check which ones timed out.
Futures.allAsList(futures).get(timeoutMillis, TimeUnit.MILLISECONDS)
? OrsuccessfulAsList
, depending on your intended semantics? – Pessimismget
call on theFuture
returned byallAsList
will throw aTimeoutException
– MacswansuccessfulAsList
returns aListenableFuture
which, whenget
is called with a timeout, throws an exception when the timeout expires. – MacswansuccessfulAsList
after usingwithTimeout
on all the futures? – PessimismExexcutor
to do this? – MacswanScheduledExecutorService
. – PessimismwithTimeout
start when it's called or whenget
is called? If the former, that seems like a good answer that I'd love for you to write-up so I could accept it. – Macswan