/** * 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(List<? extends ListenableFuture<?>> futures) { if (futures == null || futures.isEmpty()) { return ImmediateResultListenableFuture.NULL_RESULT; } else if (futures.size() == 1) { return futures.get(0); } else { return makeCompleteFuture((Iterable<? extends ListenableFuture<?>>)futures); } }
/** * 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(List<? extends ListenableFuture<?>> futures) { if (futures == null || futures.isEmpty()) { return ImmediateResultListenableFuture.NULL_RESULT; } else if (futures.size() == 1) { return futures.get(0); } else { return makeCompleteFuture((Iterable<? extends ListenableFuture<?>>)futures); } }
/** * 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); } }
/** * 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 makeCompleteFutureSingletonListTest() { List<ListenableFuture<?>> futures = Collections.singletonList(FutureUtils.immediateResultFuture(null)); ListenableFuture<?> f = FutureUtils.makeCompleteFuture(futures); assertTrue(f == futures.get(0)); }
@Test public void makeCompleteFutureSinletonCollectionTest() { ListenableFuture<?> singletonFuture = FutureUtils.immediateResultFuture(null); ListenableFuture<?> f = FutureUtils.makeCompleteFuture(Collections.singleton(singletonFuture)); assertTrue(f == singletonFuture); }
@Test public void makeCompleteFutureNullTest() { ListenableFuture<?> f = FutureUtils.makeCompleteFuture(null); assertTrue(f.isDone()); }
@Test public void makeCompleteFutureEmptyListTest() throws InterruptedException, ExecutionException { List<ListenableFuture<?>> futures = Collections.emptyList(); ListenableFuture<?> f = FutureUtils.makeCompleteFuture(futures); assertTrue(f.isDone()); assertNull(f.get()); }
@Test public void makeCompleteFutureEmptyCollectionTest() throws InterruptedException, ExecutionException { ListenableFuture<?> f = FutureUtils.makeCompleteFuture(Collections.emptySet()); assertTrue(f.isDone()); assertNull(f.get()); }
final T result) { if (result == null) { return (ListenableFuture<T>)makeCompleteFuture(futures);
final T result) { if (result == null) { return (ListenableFuture<T>)makeCompleteFuture(futures);
private static void makeCompleteFutureTest(int errorIndex) throws InterruptedException, TimeoutException, ExecutionException { List<ListenableFuture<?>> futures = makeFutures(TEST_QTY, errorIndex); ListenableFuture<?> f = FutureUtils.makeCompleteFuture(futures); verifyCompleteFuture(f, futures); assertNull(f.get()); }
@Test public void makeCompleteFutureWithResultEmptyListTest() throws InterruptedException, ExecutionException { String result = StringUtils.makeRandomString(5); List<ListenableFuture<?>> futures = Collections.emptyList(); ListenableFuture<String> f = FutureUtils.makeCompleteFuture(futures, result); assertTrue(f.isDone()); assertEquals(result, f.get()); }
@Test public void makeCompleteFutureCancelTest() { SettableListenableFuture<?> slf = new SettableListenableFuture<>(); assertTrue(FutureUtils.makeCompleteFuture(Collections.singletonList(slf)).cancel(true)); assertTrue(slf.isCancelled()); }
@Test public void makeCompleteFutureWithResultNotCompleteTest() 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.makeCompleteFuture(futures, result); futures.get(0).setResult(null); // complete now verifyCompleteFuture(f, futures); assertEquals(result, f.get()); }
@Test public void makeCompleteFutureWithResultCancelTest() { SettableListenableFuture<?> slf = new SettableListenableFuture<>(); assertTrue(FutureUtils.makeCompleteFuture(Collections.singletonList(slf), null).cancel(true)); assertTrue(slf.isCancelled()); }
@Test public void makeCompleteFutureWithNullResultTest() throws InterruptedException, TimeoutException, ExecutionException { List<ListenableFuture<?>> futures = makeFutures(TEST_QTY, -1); ListenableFuture<?> f = FutureUtils.makeCompleteFuture(futures, null); verifyCompleteFuture(f, futures); assertNull(f.get()); }
@Test public void makeCompleteFutureWithResultNullTest() throws InterruptedException, ExecutionException { String result = StringUtils.makeRandomString(5); ListenableFuture<String> f = FutureUtils.makeCompleteFuture(null, result); assertTrue(f.isDone()); assertEquals(result, f.get()); }
@Test public void makeCompleteFutureWithResultAlreadyDoneTest() throws InterruptedException, TimeoutException, ExecutionException { String result = StringUtils.makeRandomString(5); List<ListenableFuture<?>> futures = makeFutures(TEST_QTY, -1); ListenableFuture<String> f = FutureUtils.makeCompleteFuture(futures, result); verifyCompleteFuture(f, futures); assertEquals(result, f.get()); }