long remainingTime = timeoutInMs - (Clock.lastKnownForwardProgressingMillis() - startTime); try { FutureUtils.blockTillAllComplete(resultList, remainingTime); } catch (TimeoutException e) { FutureUtils.cancelIncompleteFutures(resultList, true); FutureUtils.blockTillAllComplete(resultList);
/** * This call blocks till all futures in the list have completed. If the future completed with * an error, the {@link ExecutionException} is swallowed. Meaning that this does not attempt to * verify that all futures completed successfully. If you need to know if any failed, please * use {@link #blockTillAllCompleteOrFirstError(Iterable)}. * <p> * If you need to specify a timeout to control how long to block, consider using * {@link #blockTillAllComplete(Iterable, long)}. * * @param futures Structure of futures to iterate over * @throws InterruptedException Thrown if thread is interrupted while waiting on future */ public static void blockTillAllComplete(Iterable<? extends Future<?>> futures) throws InterruptedException { countFuturesWithResult(futures, null); }
return executeWhile(asyncTask.call(), asyncTask, loopTest, timeoutMillis, timeoutProvideLastValue); } catch (Exception e) { return immediateFailureFuture(e);
@Override public <T> ListenableFuture<T> submit(Callable<T> task) { ArgumentVerifier.assertNotNull(task, "task"); try { T result = task.call(); return FutureUtils.immediateResultFuture(result); } catch (Throwable t) { return FutureUtils.immediateFailureFuture(t); } } }
/** * Similar to {@link #makeCompleteFuture(Iterable)} in that the returned future wont complete * until all the provided futures complete. However this implementation will check if any * futures failed or were canceled once all have completed. If any did not complete normally * then the returned futures state will match the state of one of the futures that did not * normally (randomly chosen). * <p> * Since the returned future wont complete until all futures complete, you may want to consider * using {@link #cancelIncompleteFuturesIfAnyFail(boolean, Iterable, boolean)} in addition to * this so that the future will resolve as soon as any failures occur. * * @since 5.0 * @param futures Collection of futures that must finish before returned future is satisfied * @return ListenableFuture which will be done once all futures provided are done */ public static ListenableFuture<?> makeFailurePropagatingCompleteFuture(Iterable<? extends ListenableFuture<?>> futures) { return makeFailurePropagatingCompleteFuture(futures, null); }
/** * An alternative to {@link #blockTillAllComplete(Iterable)}, this provides the ability to know * when all futures are complete without blocking. Unlike * {@link #blockTillAllComplete(Iterable)}, this requires that you provide a collection of * {@link ListenableFuture}'s. But will return immediately, providing a new * {@link ListenableFuture} that will be called once all the provided futures have finished. * <p> * The future returned will provide a {@code null} result, it is the responsibility of the * caller to get the actual results from the provided futures. This is designed to just be an * indicator as to when they have finished. If you need the results from the provided futures, * consider using {@link #makeCompleteListFuture(Iterable)}. You should also consider using * {@link #makeFailurePropagatingCompleteFuture(Iterable)}, it has the same semantics as this one * except it will put the returned future into an error state if any of the provided futures error. * * @since 5.3 * @param futures Collection of futures that must finish before returned future is satisfied * @return ListenableFuture which will be done once all futures provided are done */ public static ListenableFuture<?> makeCompleteFuture(Collection<? extends ListenableFuture<?>> futures) { if (futures == null || futures.isEmpty()) { return ImmediateResultListenableFuture.NULL_RESULT; } else if (futures.size() == 1) { return futures.iterator().next(); } else { return makeCompleteFuture((Iterable<? extends ListenableFuture<?>>)futures); } }
@Test public void executeWhileTest() throws InterruptedException, ExecutionException { AtomicInteger ai = new AtomicInteger(); ListenableFuture<Integer> f = FutureUtils.executeWhile(() -> FutureUtils.immediateResultFuture(ai.getAndIncrement()), (i) -> i < 10); assertTrue(f.isDone()); assertEquals(10, f.get().intValue()); }
@Override public <T> ListenableFuture<T> submit(Callable<T> task, TaskPriority priority) { submitCallableCalled = true; return FutureUtils.immediateFailureFuture(new UnsupportedOperationException()); }
@Test public void blockTillAllCompleteNullTest() throws InterruptedException { FutureUtils.blockTillAllComplete(null); // should return immediately }
@Test public void makeCompleteFutureSinletonCollectionTest() { ListenableFuture<?> singletonFuture = FutureUtils.immediateResultFuture(null); ListenableFuture<?> f = FutureUtils.makeCompleteFuture(Collections.singleton(singletonFuture)); assertTrue(f == singletonFuture); }
@Test public void countFuturesWithResultTest() throws InterruptedException { List<ListenableFuture<Boolean>> futures = new ArrayList<>(TEST_QTY * 2); for (int i = 0; i < TEST_QTY * 2; i++) { futures.add(FutureUtils.immediateResultFuture(i % 2 == 1)); } assertEquals(TEST_QTY, FutureUtils.countFuturesWithResult(futures, false)); }
final boolean ignoreFailedFutures) { if (futures == null) { return immediateResultFuture(Collections.<T>emptyList()); makeCompleteListFuture(futures); final SettableListenableFuture<List<T>> result = new CancelDelegateSettableListenableFuture<>(completeFuture, null);
@Test public void scheduleWhileAlreadyDoneWithFinalResultTest() throws Exception { TestableScheduler scheduler = new TestableScheduler(); Object result = new Object(); ListenableFuture<Object> f = FutureUtils.scheduleWhile(scheduler, 2, FutureUtils.immediateResultFuture(result), () -> result, (o) -> false); assertTrue(f.isDone()); assertTrue(result == f.get()); }
@Override public void handleFailure(Throwable t) { if (! canceled.get() && canceled.compareAndSet(false, true)) { FutureUtils.cancelIncompleteFutures(futures, interruptThread); } } }
/** * A potentially more performant option than {@link #makeCompleteFuture(List)} when only a * listener invocation is desired after all the futures complete. This is effective an async * implementation of {@link #blockTillAllComplete(Iterable)}. If the listener needs to be * invoked on another thread than one of the provided futures please use * {@link #invokeAfterAllComplete(Collection, Runnable, Executor)}. Please see * {@link ListenableFuture#addListener(Runnable)} for more information on execution without an * {@link Executor}. * <p> * It is critical that the collection is NOT modified while this is invoked. A change in the * futures contained in the collection will lead to unreliable behavior with the exectuion of the * listener. * * @param futures Futures that must complete before listener is invoked * @param listener Invoked once all the provided futures have completed */ public static void invokeAfterAllComplete(Collection<? extends ListenableFuture<?>> futures, Runnable listener) { invokeAfterAllComplete(futures, listener, null); }
/** * Similar to {@link #scheduleWhile(SubmitterScheduler, long, boolean, Callable, Predicate)} * except that no executor is needed because the callable instead will return a future from the * provided async submission (which may be a scheduled task or otherwise). * <p> * In the end this is just another way to have a loop of async actions, checking results as they * are provided but not resolving the returned future till the async action completes. * * @param <T> The result object type returned by the task and provided by the future * @param asyncTask Callable to produce a {@link ListenableFuture} for when a result is ready * @param loopTest The test to check the ready result to see if we need to keep looping * @return Future that will resolve once returned {@link Predicate} returns {@code false} */ public static <T> ListenableFuture<T> executeWhile(Callable<? extends ListenableFuture<? extends T>> asyncTask, Predicate<? super T> loopTest) { return executeWhile(asyncTask, loopTest, -1, false); }
@Test public void immediateResultFutureAddListenerTest() { ListenableFuture<?> testFuture = FutureUtils.immediateResultFuture(null); ImmediateListenableFutureTest.addListenerTest(testFuture); }
@Test public void makeCompleteListFutureEmptyListTest() { List<ListenableFuture<?>> futures = Collections.emptyList(); ListenableFuture<List<ListenableFuture<?>>> f = FutureUtils.makeCompleteListFuture(futures); assertTrue(f.isDone()); }
@Override public <T> ListenableFuture<T> submit(Runnable task, T result) { ArgumentVerifier.assertNotNull(task, "task"); try { task.run(); return FutureUtils.immediateResultFuture(result); } catch (Throwable t) { return FutureUtils.immediateFailureFuture(t); } }
@Test public void makeFailurePropagatingCompleteFutureEmptyListTest() { List<ListenableFuture<?>> futures = Collections.emptyList(); ListenableFuture<?> f = FutureUtils.makeFailurePropagatingCompleteFuture(futures); assertTrue(f.isDone()); }