public interface Awaitable<T>
Core abstraction for asynchronous computations in Groovy.
Awaitable represents a computation that may not have completed
yet. It serves as both an instance type (the result of async
methods and the input to await) and a static API surface for
combinators, factories, and configuration.
Static combinators (all return Awaitable, suitable for use
with await). Multi-argument await desugars to
Awaitable.all(...), so await(a, b) and await a, b
are shorthand for await Awaitable.all(a, b):
Promise.any(); only fails when all sources fail)Static factories and conversion:
AwaitableAwaitableAwaitableInstance continuations provide ergonomic composition without exposing raw CompletableFuture APIs:
Third-party frameworks (RxJava, Reactor, etc.) can integrate by registering an AwaitableAdapter via AwaitableAdapterRegistry.
The default implementation, GroovyPromise, delegates to CompletableFuture but users never need to depend on that detail.
T - the result type| Type Params | Return Type | Name and description |
|---|---|---|
|
public static Awaitable<List<Object>> |
all(Object sources)Returns an Awaitable that completes when all given sources
complete successfully, with a list of their results in order. |
|
public static Awaitable<List<AwaitResult<Object>>> |
allSettled(Object sources)Returns an Awaitable that completes when all given sources
have settled (succeeded or failed), with a list of AwaitResult
objects describing each outcome. |
<T> |
public static Awaitable<T> |
any(Object sources)Returns an Awaitable that completes when the first of the given
sources completes, with the winner's result.
|
|
public boolean |
cancel()Attempts to cancel the computation. |
|
public Awaitable<T> |
completeOnTimeout(T fallback, long duration, TimeUnit unit)Returns a new Awaitable that completes with the supplied fallback
value if this computation does not finish before the timeout expires. |
<T> |
public static Awaitable<T> |
completeOnTimeout(Object source, T fallback, long duration, TimeUnit unit)Adapts the given source and returns a new awaitable that yields the supplied fallback value if the timeout expires first. |
|
public Awaitable<T> |
completeOnTimeoutMillis(T fallback, long timeoutMillis)Returns a new Awaitable that completes with the supplied fallback
value if this computation does not finish before the timeout expires. |
<T> |
public static Awaitable<T> |
completeOnTimeoutMillis(Object source, T fallback, long timeoutMillis)Adapts the given source and returns a new awaitable that yields the supplied fallback value if the timeout expires first. |
|
public static Awaitable<Void> |
delay(long milliseconds)Returns an Awaitable that completes after the specified delay.
|
|
public static Awaitable<Void> |
delay(long duration, TimeUnit unit)Returns an Awaitable that completes after the specified delay. |
|
public Awaitable<T> |
exceptionally(Function<Throwable, ? extends T> fn)Returns a new Awaitable that, if this one completes exceptionally,
applies the given function to the exception to produce a recovery value.
|
<T> |
public static Awaitable<T> |
failed(Throwable error)Returns an already-failed Awaitable with the given exception. |
<T> |
public static Awaitable<T> |
first(Object sources)Returns an Awaitable that completes with the result of the first
source that succeeds. |
<T> |
public static Awaitable<T> |
from(Object source)Converts the given source to an Awaitable. |
|
public T |
get()Blocks until the computation completes and returns the result. |
|
public T |
get(long timeout, TimeUnit unit)Blocks until the computation completes or the timeout expires. |
|
public static Executor |
getExecutor()Returns the current executor used for async operations. |
<T> |
public static Awaitable<T> |
go(Closure<T> closure)Spawns a lightweight task. |
<U> |
public Awaitable<U> |
handle(BiFunction<? super T, Throwable, ? extends U> fn)Returns a new Awaitable that handles both the successful and the
exceptional completion paths in a single continuation. |
|
public boolean |
isCancelled()Returns true if the computation was cancelled before completing normally. |
|
public boolean |
isCompletedExceptionally()Returns true if this computation completed exceptionally
(including cancellation). |
|
public boolean |
isDone()Returns true if the computation has completed (normally,
exceptionally, or via cancellation). |
|
public static boolean |
isVirtualThreadsAvailable()Returns true if the running JVM supports virtual threads (JDK 21+). |
<T> |
public static Awaitable<T> |
of(T value)Returns an already-completed Awaitable with the given value.
|
|
public Awaitable<T> |
orTimeout(long duration, TimeUnit unit)Returns a new Awaitable that fails with TimeoutException
if this computation does not complete within the specified duration. |
<T> |
public static Awaitable<T> |
orTimeout(Object source, long duration, TimeUnit unit)Adapts the given source and applies a non-blocking fail-fast timeout with explicit TimeUnit. |
|
public Awaitable<T> |
orTimeoutMillis(long timeoutMillis)Returns a new Awaitable that fails with TimeoutException
if this computation does not complete within the specified milliseconds. |
<T> |
public static Awaitable<T> |
orTimeoutMillis(Object source, long timeoutMillis)Adapts the given source to an Awaitable and applies a non-blocking
fail-fast timeout. |
|
public static void |
setExecutor(Executor executor)Sets the executor to use for async operations. |
<U> |
public Awaitable<U> |
then(Function<? super T, ? extends U> fn)Returns a new Awaitable whose result is obtained by applying the
given function to this awaitable's result when it completes. |
|
public Awaitable<Void> |
thenAccept(Consumer<? super T> action)Returns a new Awaitable that, when this one completes normally,
invokes the given consumer and completes with null. |
<U> |
public Awaitable<U> |
thenCompose(Function<? super T, ? extends Awaitable<U>> fn)Returns a new Awaitable produced by applying the given async
function to this awaitable's result, flattening the nested Awaitable.
|
|
public CompletableFuture<T> |
toCompletableFuture()Converts this Awaitable to a JDK CompletableFuture
for interoperability with APIs that require it. |
|
public Awaitable<T> |
whenComplete(BiConsumer<? super T, ? super Throwable> action)Returns a new Awaitable that invokes the given action when this
computation completes, regardless of success or failure. |
<T> |
public static T |
withScope(Closure<T> body)Convenience delegate to AsyncScope.withScope. |
Returns an Awaitable that completes when all given sources
complete successfully, with a list of their results in order.
Like JavaScript's Promise.all(), the combined awaitable fails as
soon as the first source fails. Remaining sources are not cancelled
automatically; cancel them explicitly if that is required by your workflow.
Unlike blocking APIs, this returns immediately and the caller should
await the result. All three forms below are equivalent:
// Explicit all() call
def results = await Awaitable.all(task1, task2, task3)
// Parenthesized multi-arg await — syntactic sugar
def results = await(task1, task2, task3)
// Unparenthesized multi-arg await — most concise form
def results = await task1, task2, task3
sources - the awaitables, futures, or adapted objects to wait for Returns an Awaitable that completes when all given sources
have settled (succeeded or failed), with a list of AwaitResult
objects describing each outcome.
Never throws for individual failures; they are captured in the result list.
def results = await Awaitable.allSettled(task1, task2)
results.each { println it.success ? it.value : it.error }
sources - the awaitables to settle Returns an Awaitable that completes when the first of the given
sources completes, with the winner's result.
def winner = await Awaitable.any(task1, task2)
sources - the awaitables to raceAttempts to cancel the computation. If the computation has not yet started or is still running, it will be cancelled with a CancellationException.
true if the computation was successfully cancelled Returns a new Awaitable that completes with the supplied fallback
value if this computation does not finish before the timeout expires.
fallback - the value to use when the timeout expiresduration - the timeout durationunit - the time unitAdapts the given source and returns a new awaitable that yields the supplied fallback value if the timeout expires first.
source - the async source to wait forfallback - the fallback value to use on timeoutduration - the timeout durationunit - the time unitT - the result type Returns a new Awaitable that completes with the supplied fallback
value if this computation does not finish before the timeout expires.
fallback - the value to use when the timeout expirestimeoutMillis - the timeout duration in millisecondsAdapts the given source and returns a new awaitable that yields the supplied fallback value if the timeout expires first.
source - the async source to wait forfallback - the fallback value to use on timeouttimeoutMillis - the timeout duration in millisecondsT - the result type Returns an Awaitable that completes after the specified delay.
Does not block any thread; the delay is handled by a scheduled executor.
await Awaitable.delay(1000) // pause for 1 second
milliseconds - the delay in milliseconds (must be ≥ 0) Returns an Awaitable that completes after the specified delay.
duration - the delay duration (must be ≥ 0)unit - the time unit Returns a new Awaitable that, if this one completes exceptionally,
applies the given function to the exception to produce a recovery value.
The throwable passed to the function is deeply unwrapped to strip JDK
wrapper layers.
fn - the recovery function Returns an already-failed Awaitable with the given exception.
Useful for signaling a synchronous error from an API that returns
Awaitable, without spawning a thread:
if (id < 0) return Awaitable.failed(new IllegalArgumentException("negative id"))
error is nullerror - the exception to wrap; must not be nullT - the nominal result type (never produced, since the awaitable is failed) Returns an Awaitable that completes with the result of the first
source that succeeds. Individual failures are silently absorbed; only
when all sources have failed does the returned awaitable reject
with an IllegalStateException whose
{@linkplain Throwable#getSuppressed() suppressed} array contains every
individual error.
This is the Groovy equivalent of JavaScript's Promise.any().
Contrast with any(Object...) which returns the first result to
complete regardless of success or failure.
Typical use cases:
// Hedged HTTP request
def response = await Awaitable.first(
fetchFromPrimary(),
fetchFromFallback(),
fetchFromCache()
)
sources is null,
empty, or contains null elementssources - the awaitables to race for first success; must not be
null, empty, or contain null elementsT - the result type Converts the given source to an Awaitable.
If the source is already an Awaitable, it is returned as-is.
Otherwise, the AwaitableAdapterRegistry is consulted to find a
suitable adapter. Built-in adapters handle CompletableFuture,
CompletionStage, and
Future; third-party frameworks can register
additional adapters via the registry.
This is the recommended entry point for converting external async types
to Awaitable:
Awaitable<String> aw = Awaitable.from(someCompletableFuture)
Awaitable<Integer> aw2 = Awaitable.from(someReactorMono)
source - the source object; if null, returns a completed
awaitable with a null resultT - the result typeBlocks until the computation completes and returns the result.
Blocks until the computation completes or the timeout expires.
timeout - the maximum time to waitunit - the time unit of the timeout argument Returns the current executor used for async operations.
On JDK 21+, the default is a virtual-thread-per-task executor.
On JDK 17–20, a bounded cached daemon thread pool is used
(size controlled by the groovy.async.parallelism system property,
default 256).
This method is thread-safe and may be called from any thread.
nullSpawns a lightweight task.
closure - the task bodyT - the result type Returns a new Awaitable that handles both the successful and the
exceptional completion paths in a single continuation.
The supplied throwable is transparently unwrapped so the handler sees the original failure. This provides a single place for success/failure projection, combining both paths in one callback.
fn - the handler receiving either the value or the failureU - the projected result type Returns true if the computation was cancelled before completing normally.
true if cancelled Returns true if this computation completed exceptionally
(including cancellation).
true if completed with an error or cancellation Returns true if the computation has completed (normally,
exceptionally, or via cancellation).
true if complete Returns true if the running JVM supports virtual threads (JDK 21+).
When virtual threads are available, the default executor uses a virtual-thread-per-task strategy that scales to millions of concurrent tasks with minimal memory overhead.
true if virtual threads are available Returns an already-completed Awaitable with the given value.
Useful for returning a pre-computed result from an API that requires
an Awaitable return type.
value - the result value (may be null)T - the result type Returns a new Awaitable that fails with TimeoutException
if this computation does not complete within the specified duration.
duration - the timeout durationunit - the time unitAdapts the given source and applies a non-blocking fail-fast timeout with explicit TimeUnit.
source - the async source to time outduration - the timeout durationunit - the time unitT - the result type Returns a new Awaitable that fails with TimeoutException
if this computation does not complete within the specified milliseconds.
Unlike get(long, TimeUnit), this is a non-blocking, composable
timeout combinator: it returns another Awaitable that can itself
be awaited, chained, or passed to all(Object...) / any(Object...).
timeoutMillis - the timeout duration in milliseconds Adapts the given source to an Awaitable and applies a non-blocking
fail-fast timeout. Returns a new awaitable that fails with
TimeoutException if the source does not complete before the
deadline elapses.
The source may be a Groovy Awaitable, a JDK CompletableFuture/CompletionStage, or any type supported by AwaitableAdapterRegistry. This provides a concise timeout combinator that returns another awaitable rather than requiring structural timeout blocks.
source - the async source to time outtimeoutMillis - the timeout duration in millisecondsT - the result type Sets the executor to use for async operations.
Pass null to reset to the default executor. The change
takes effect immediately for all subsequent async method
invocations; tasks already in flight continue using the executor
that launched them.
This method is thread-safe and may be called from any thread.
executor - the executor to use, or null to restore
the default executor Returns a new Awaitable whose result is obtained by applying the
given function to this awaitable's result when it completes.
fn - the mapping functionU - the type of the mapped result Returns a new Awaitable that, when this one completes normally,
invokes the given consumer and completes with null.
Useful at API boundaries where you need to attach logging, metrics, or other side effects without blocking for the result.
action - the side-effecting consumer to invoke on success Returns a new Awaitable produced by applying the given async
function to this awaitable's result, flattening the nested Awaitable.
This is the monadic flatMap operation for awaitables.
fn - the async mapping function that returns an AwaitableU - the type of the inner awaitable's result Converts this Awaitable to a JDK CompletableFuture
for interoperability with APIs that require it.
CompletableFuture representing this computation Returns a new Awaitable that invokes the given action when this
computation completes, regardless of success or failure.
The supplied throwable is transparently unwrapped so handlers see the original failure rather than ExecutionException / CompletionException wrappers.
action - the completion callback receiving the result or failureConvenience delegate to AsyncScope.withScope. Creates a structured concurrency scope, executes the closure within it, and ensures all child tasks complete before returning.
body - the closure receiving the scopeT - the result type