/** * 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); }
/** * 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); }
@Test public void makeFailurePropagatingCompleteFutureEmptyListTest() { List<ListenableFuture<?>> futures = Collections.emptyList(); ListenableFuture<?> f = FutureUtils.makeFailurePropagatingCompleteFuture(futures); assertTrue(f.isDone()); }
@Test public void makeFailurePropagatingCompleteFutureAlreadyDoneFuturesTest() { List<ListenableFuture<?>> futures = new ArrayList<>(TEST_QTY); for (int i = 0; i < TEST_QTY; i++) { SettableListenableFuture<?> future = new SettableListenableFuture<>(); future.setResult(null); futures.add(future); } ListenableFuture<?> f = FutureUtils.makeFailurePropagatingCompleteFuture(futures); assertTrue(f.isDone()); }
@Test public void makeFailurePropagatingCompleteFutureNullTest() { ListenableFuture<?> f = FutureUtils.makeFailurePropagatingCompleteFuture(null); assertTrue(f.isDone()); }
@Test public void makeFailurePropagatingCompleteFutureCancelTest() { SettableListenableFuture<?> slf = new SettableListenableFuture<>(); assertTrue(FutureUtils.makeFailurePropagatingCompleteFuture(Collections.singletonList(slf)).cancel(true)); assertTrue(slf.isCancelled()); }
@Test public void makeFailurePropagatingCompleteFutureWithResultEmptyListTest() throws InterruptedException, ExecutionException { String result = StringUtils.makeRandomString(5); List<ListenableFuture<?>> futures = Collections.emptyList(); ListenableFuture<String> f = FutureUtils.makeFailurePropagatingCompleteFuture(futures, result); assertTrue(f.isDone()); assertEquals(result, f.get()); }
@Test public void makeFailurePropagatingCompleteFutureWithResultCancelTest() { SettableListenableFuture<?> slf = new SettableListenableFuture<>(); assertTrue(FutureUtils.makeFailurePropagatingCompleteFuture(Collections.singletonList(slf), null).cancel(true)); assertTrue(slf.isCancelled()); }
@Test public void makeFailurePropagatingCompleteFutureWithResultNotCompleteTest() throws InterruptedException, TimeoutException, ExecutionException { String result = StringUtils.makeRandomString(5); List<SettableListenableFuture<?>> futures = new ArrayList<>(TEST_QTY); for (int i = 0; i < TEST_QTY; i++) { SettableListenableFuture<?> future = new SettableListenableFuture<>(); if (i != 0) { future.setResult(null); } futures.add(future); } ListenableFuture<String> f = FutureUtils.makeFailurePropagatingCompleteFuture(futures, result); futures.get(0).setResult(null); verifyCompleteFuture(f, futures); assertEquals(result, f.get()); }
@Test public void makeFailurePropagatingCompleteFutureTest() throws InterruptedException, TimeoutException, ExecutionException { List<ListenableFuture<?>> futures = makeFutures(TEST_QTY, -1); ListenableFuture<?> f = FutureUtils.makeFailurePropagatingCompleteFuture(futures); verifyCompleteFuture(f, futures); assertNull(f.get()); }
@Test public void makeFailurePropagatingCompleteFutureWithNullResultTest() throws InterruptedException, TimeoutException, ExecutionException { List<ListenableFuture<?>> futures = makeFutures(TEST_QTY, -1); ListenableFuture<?> f = FutureUtils.makeFailurePropagatingCompleteFuture(futures, null); verifyCompleteFuture(f, futures); assertNull(f.get()); }
@Test public void makeFailurePropagatingCompleteFuturePropagateFailureTest() { List<ListenableFuture<?>> futures = makeFutures(TEST_QTY, TEST_QTY / 2); ListenableFuture<?> f = FutureUtils.makeFailurePropagatingCompleteFuture(futures); try { f.get(); fail("Exception should have thrown"); } catch (ExecutionException e) { // expected } catch (InterruptedException e) { fail("Interrupted?"); } }
@Test public void makeFailurePropagatingCompleteFuturePropagateCancelTest() { SettableListenableFuture<?> slf = new SettableListenableFuture<>(); assertTrue(slf.cancel(false)); ListenableFuture<?> f = FutureUtils.makeFailurePropagatingCompleteFuture(Collections.singletonList(slf)); assertTrue(f.isDone()); assertTrue(f.isCancelled()); }
@Test public void makeFailurePropagatingCompleteFutureWithResultAlreadyDoneTest() throws InterruptedException, TimeoutException, ExecutionException { String result = StringUtils.makeRandomString(5); List<ListenableFuture<?>> futures = makeFutures(TEST_QTY, -1); ListenableFuture<String> f = FutureUtils.makeFailurePropagatingCompleteFuture(futures, result); verifyCompleteFuture(f, futures); assertEquals(result, f.get()); }
@Test public void makeFailurePropagatingCompleteFutureWithResultNullTest() throws InterruptedException, ExecutionException { String result = StringUtils.makeRandomString(5); ListenableFuture<String> f = FutureUtils.makeFailurePropagatingCompleteFuture(null, result); assertTrue(f.isDone()); assertEquals(result, f.get()); }