Class AsyncFut
Asyncc. Each combinator returns a
CompletableFuture instead of taking an error-first final callback — the same
vocabulary, the JDK's promise shape.
AsyncFut is implemented in terms of Asyncc (via WrapFuture), so
every combinator inherits the v0.2.x concurrency hardening: at-most-once final callback,
lost-update-free counters, slot-write-before-counter-increment ordering, no
ArrayList resize race, the ParallelLimit <= limit-in-flight
invariant, etc. The wrapper layer adds one CompletableFuture allocation per call;
use Asyncc directly if you need to shave that ~5 µs.
Task shape
Most combinators take a list (or function) of Suppliers that produce a
CompletionStage. The supplier is invoked when the combinator chooses to start that
task — this is crucial for Series, ParallelLimit, and Race,
where eagerly-started futures would defeat the point. If you already have an in-flight
future, wrap it as () -> theFuture.
Quick examples
// Parallel: fan out N tasks, collect their results
CompletableFuture<List<String>> both = AsyncFut.Parallel(List.of(
() -> CompletableFuture.supplyAsync(this::fetchA, exec),
() -> CompletableFuture.supplyAsync(this::fetchB, exec)
));
both.thenAccept(results -> reply.send(combine(results.get(0), results.get(1))));
// ParallelLimit: same but with a concurrency cap
CompletableFuture<List<Path>> downloaded = AsyncFut.ParallelLimit(8, downloads);
// Series: sequential, collect each result
CompletableFuture<List<Step>> chain = AsyncFut.Series(List.of(
() -> validate(req), () -> persist(req), () -> notify(req)
));
// Race: first completer wins
CompletableFuture<String> winner = AsyncFut.Race(List.of(
() -> fromPrimary(), () -> fromReplica()
));
// Map: async transform preserving input order
CompletableFuture<List<Profile>> profiles =
AsyncFut.Map(userIds, id -> fetchProfileAsync(id));
// Reduce: sequential fold with an async reducer
CompletableFuture<BigDecimal> total =
AsyncFut.Reduce(transactions, BigDecimal.ZERO,
(acc, txn) -> computeAsync(acc, txn));
// Times: run the same task N times
CompletableFuture<List<Sample>> samples =
AsyncFut.Times(8, i -> generateSampleAsync(i));
// Each: fire-and-forget per element, complete with Void when all done
CompletableFuture<Void> sent =
AsyncFut.Each(users, u -> sendEmailAsync(u));
Error semantics
Each combinator's returned future completes exceptionally with the first error any task
produces (just like Asyncc's short-circuit). Subsequent task completions are
absorbed by the at-most-once guard.
Interop
You can mix Asyncc and AsyncFut freely via WrapFuture:
// AsyncFut.Parallel inside an Asyncc.Waterfall step:
Asyncc.Waterfall(List.of(
c -> c.success(parseRequest(raw)),
(req, c) -> WrapFuture.fromStage(
AsyncFut.Parallel(List.of(
() -> lookupA(req), () -> lookupB(req)
))
).run(c)
), wrap(finalValue -> reply.send(finalValue)));
- Since:
- 0.2.7
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionstatic <T> CompletableFuture<Void>Each(int limit, Iterable<T> input, Function<? super T, ? extends CompletionStage<Void>> task) Fire-and-forget per element with a concurrency cap.static <T> CompletableFuture<Void>Each(Iterable<T> input, Function<? super T, ? extends CompletionStage<Void>> task) Unlimited-concurrency convenience forEach(int, Iterable, Function).static <T,V> CompletableFuture<List<V>> Map(Iterable<T> input, Function<? super T, ? extends CompletionStage<V>> mapper) Runmapper(element)concurrently for each element ofinput; return a future of the per-element values in input order.static <T> CompletableFuture<List<T>>Parallel(Supplier<? extends CompletionStage<T>> a, Supplier<? extends CompletionStage<T>> b) Two-task convenience.static <T> CompletableFuture<List<T>>Parallel(Supplier<? extends CompletionStage<T>> a, Supplier<? extends CompletionStage<T>> b, Supplier<? extends CompletionStage<T>> c) Three-task convenience.static <T> CompletableFuture<List<T>>Parallel(List<Supplier<? extends CompletionStage<T>>> tasks) Run all tasks concurrently; return a future of their results in the same order as the input list.static <T> CompletableFuture<List<T>>ParallelLimit(int limit, List<Supplier<? extends CompletionStage<T>>> tasks) LikeParallel(java.util.List<java.util.function.Supplier<? extends java.util.concurrent.CompletionStage<T>>>)but with at mostlimittasks in flight at any time.static <T> CompletableFuture<T>Race(List<Supplier<? extends CompletionStage<T>>> tasks) Run all tasks concurrently; complete with the value of whichever finishes first.static <T,V> CompletableFuture<V> Reduce(Iterable<T> input, V identity, BiFunction<V, ? super T, ? extends CompletionStage<V>> reducer) Sequential fold with an async reducer.static <T> CompletableFuture<List<T>>Series(List<Supplier<? extends CompletionStage<T>>> tasks) Run tasks one after another.static <T> CompletableFuture<List<T>>Times(int n, IntFunction<? extends CompletionStage<T>> task) Runtask(i)foriin[0, n)concurrently; return a future of the per-iteration results iniorder.
-
Method Details
-
Parallel
public static <T> CompletableFuture<List<T>> Parallel(List<Supplier<? extends CompletionStage<T>>> tasks) Run all tasks concurrently; return a future of their results in the same order as the input list. Short-circuits on the first failure. -
Parallel
public static <T> CompletableFuture<List<T>> Parallel(Supplier<? extends CompletionStage<T>> a, Supplier<? extends CompletionStage<T>> b) Two-task convenience. -
Parallel
public static <T> CompletableFuture<List<T>> Parallel(Supplier<? extends CompletionStage<T>> a, Supplier<? extends CompletionStage<T>> b, Supplier<? extends CompletionStage<T>> c) Three-task convenience. -
ParallelLimit
public static <T> CompletableFuture<List<T>> ParallelLimit(int limit, List<Supplier<? extends CompletionStage<T>>> tasks) LikeParallel(java.util.List<java.util.function.Supplier<? extends java.util.concurrent.CompletionStage<T>>>)but with at mostlimittasks in flight at any time. -
Series
public static <T> CompletableFuture<List<T>> Series(List<Supplier<? extends CompletionStage<T>>> tasks) Run tasks one after another. The returned future completes with a list of each task's value in input order. Short-circuits on the first failure. -
Race
Run all tasks concurrently; complete with the value of whichever finishes first. Errors from non-winning tasks are absorbed by the at-most-once guard. -
Map
public static <T,V> CompletableFuture<List<V>> Map(Iterable<T> input, Function<? super T, ? extends CompletionStage<V>> mapper) Runmapper(element)concurrently for each element ofinput; return a future of the per-element values in input order. -
Reduce
public static <T,V> CompletableFuture<V> Reduce(Iterable<T> input, V identity, BiFunction<V, ? super T, ? extends CompletionStage<V>> reducer) Sequential fold with an async reducer.reducer(acc, element)is invoked once per element, in input order, with the running accumulator. The returned future completes with the final accumulator value. -
Times
public static <T> CompletableFuture<List<T>> Times(int n, IntFunction<? extends CompletionStage<T>> task) Runtask(i)foriin[0, n)concurrently; return a future of the per-iteration results iniorder. -
Each
public static <T> CompletableFuture<Void> Each(int limit, Iterable<T> input, Function<? super T, ? extends CompletionStage<Void>> task) Fire-and-forget per element with a concurrency cap.task(element)runs for each element concurrently up tolimitin-flight; the returned future completes withnullwhen all tasks finish, or exceptionally on the first failure. No per-element value is collected. -
Each
public static <T> CompletableFuture<Void> Each(Iterable<T> input, Function<? super T, ? extends CompletionStage<Void>> task) Unlimited-concurrency convenience forEach(int, Iterable, Function).
-