@Test public void testFireOnceMajorityFailed1() { CompletableFuture<Boolean> f1 = new CompletableFuture<>(); CompletableFuture<Boolean> f2 = new CompletableFuture<>(); List<CompletableFuture<Boolean>> responses = Lists.newArrayList( f1, f2, completedFuture(Boolean.TRUE) ); CompletableFuture<Boolean> collector = majorityResponse(responses, input -> input); f1.completeExceptionally(new Exception()); assertFalse(collector.isDone()); f2.completeExceptionally(new Exception()); assertTrue(collector.isDone()); assertFalse(Futures.getUnchecked(collector)); }
@Nonnull public static <U> CompletableFuture<Boolean> majorityResponse(@Nonnull List<? extends CompletableFuture<U>> responses, @Nonnull Predicate<U> isSuccess) { CompletableFuture<Boolean> future = new CompletableFuture<>(); MajorityCollector<U> collector = new MajorityCollector<>(responses.size(), isSuccess, future); for (CompletableFuture<U> response : responses) { response.handle(collector); } if (responses.isEmpty()) { collector.checkComplete(); } return future; }
MajorityCollector implements BiFunction<T, Throwable, Boolean> { @Nonnull public static <U> CompletableFuture<Boolean> majorityResponse(@Nonnull List<? extends CompletableFuture<U>> responses, @Nonnull Predicate<U> isSuccess) { CompletableFuture<Boolean> future = new CompletableFuture<>(); MajorityCollector<U> collector = new MajorityCollector<>(responses.size(), isSuccess, future); for (CompletableFuture<U> response : responses) { response.handle(collector); } if (responses.isEmpty()) { collector.checkComplete(); } return future; } }
MajorityCollector implements BiFunction<T, Throwable, Boolean> { @Nonnull public static <U> CompletableFuture<Boolean> majorityResponse(@Nonnull List<? extends CompletableFuture<U>> responses, @Nonnull Predicate<U> isSuccess) { CompletableFuture<Boolean> future = new CompletableFuture<>(); MajorityCollector<U> collector = new MajorityCollector<>(responses.size(), isSuccess, future); for (CompletableFuture<U> response : responses) { response.handle(collector); } if (responses.isEmpty()) { collector.checkComplete(); } return future; } private  MajorityCollector(@Nonnegative int totalNum, @Nonnull Predicate<T> isSuccess, CompletableFuture<Boolean> future); }
MajorityCollector implements BiFunction<T, Throwable, Boolean> { @Nonnull public static <U> CompletableFuture<Boolean> majorityResponse(@Nonnull List<? extends CompletableFuture<U>> responses, @Nonnull Predicate<U> isSuccess) { CompletableFuture<Boolean> future = new CompletableFuture<>(); MajorityCollector<U> collector = new MajorityCollector<>(responses.size(), isSuccess, future); for (CompletableFuture<U> response : responses) { response.handle(collector); } if (responses.isEmpty()) { collector.checkComplete(); } return future; } private  MajorityCollector(@Nonnegative int totalNum, @Nonnull Predicate<T> isSuccess, CompletableFuture<Boolean> future); @Nonnull static CompletableFuture<Boolean> majorityResponse(@Nonnull List<? extends CompletableFuture<U>> responses, @Nonnull Predicate<U> isSuccess); @Override Boolean apply(T result, Throwable t); }
MajorityCollector implements BiFunction<T, Throwable, Boolean> { @Nonnull public static <U> CompletableFuture<Boolean> majorityResponse(@Nonnull List<? extends CompletableFuture<U>> responses, @Nonnull Predicate<U> isSuccess) { CompletableFuture<Boolean> future = new CompletableFuture<>(); MajorityCollector<U> collector = new MajorityCollector<>(responses.size(), isSuccess, future); for (CompletableFuture<U> response : responses) { response.handle(collector); } if (responses.isEmpty()) { collector.checkComplete(); } return future; } private  MajorityCollector(@Nonnegative int totalNum, @Nonnull Predicate<T> isSuccess, CompletableFuture<Boolean> future); @Nonnull static CompletableFuture<Boolean> majorityResponse(@Nonnull List<? extends CompletableFuture<U>> responses, @Nonnull Predicate<U> isSuccess); @Override Boolean apply(T result, Throwable t);  }