Package: groovy.concurrent

## [Java] Interface Awaitable<T>

-     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)`:

  - all(Object...) Awaitable.all(a, b, c) — waits for all tasks to complete, returning their results in order
  - any(Object...) Awaitable.any(a, b) — returns the result of the first task to complete
  - first(Object...) Awaitable.first(a, b, c) — returns the result of the first task to complete successfully (like JavaScript's `Promise.any()`; only fails when all sources fail)
  - allSettled(Object...) Awaitable.allSettled(a, b) — waits for all tasks to settle (succeed or fail), returning an AwaitResult list
  - delay(long) Awaitable.delay(ms) — completes after a non-blocking delay
  - orTimeoutMillis(Object, long) Awaitable.orTimeoutMillis(task, ms) — fails with TimeoutException if the task does not complete in time
  - Awaitable.completeOnTimeoutMillis(task, fallback, ms) — uses a fallback value when the timeout expires

  Static factories and conversion:

  - from(Object) Awaitable.from(source) — converts any supported async type (CompletableFuture, CompletionStage, Future, etc.) to an `Awaitable`
  - of(Object) Awaitable.of(value) — wraps an already-available value in a completed `Awaitable`
  - failed(Throwable) Awaitable.failed(error) — wraps an exception in an immediately-failed `Awaitable`
  - `Awaitable.go { ...` } — lightweight task spawn (Groovy extension method)

  Instance continuations provide ergonomic composition without exposing raw CompletableFuture APIs:

  - then(Function) and thenCompose(Function) for success chaining
  - thenAccept(Consumer) for side-effecting continuations
  - exceptionally(Function), whenComplete(BiConsumer), and handle(BiFunction) for failure/completion handling
  - orTimeout(long, TimeUnit) and completeOnTimeout(Object, long, TimeUnit) for deadline composition

  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.

  Type Parameters:
    `T` - the result type
  See Also:
    GroovyPromise
    AwaitableAdapter
  Since:
    6.0.0

- - ### Methods Summary

    Methods
    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(Supplier<T> supplier)` Spawns a lightweight task on the default executor.
    `<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(Function<AsyncScope, T> body)` Convenience delegate to AsyncScope.withScope.

- - ### Method Detail

    - #### 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.

      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

      Parameters:
        `sources` - the awaitables, futures, or adapted objects to wait for
      Returns:
        an awaitable that resolves to a list of results

    - #### 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.

      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 }

      Parameters:
        `sources` - the awaitables to settle
      Returns:
        an awaitable that resolves to a list of settled results

    - #### <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.

           def winner = await Awaitable.any(task1, task2)

      Parameters:
        `sources` - the awaitables to race
      Returns:
        an awaitable that resolves to the first completed result

    - #### public boolean cancel()

      Attempts to cancel the computation. If the computation has not yet started or is still running, it will be cancelled with a CancellationException.

      Returns:
        `true` if the computation was successfully cancelled

    - #### 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.

      Parameters:
        `fallback` - the value to use when the timeout expires
        `duration` - the timeout duration
        `unit` - the time unit
      Returns:
        a new awaitable that yields either the original result or the fallback
      Since:
        6.0.0

    - #### <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.

      Parameters:
        `source` - the async source to wait for
        `fallback` - the fallback value to use on timeout
        `duration` - the timeout duration
        `unit` - the time unit
      Type Parameters:
        `T` - the result type
      Returns:
        a new awaitable yielding either the original result or the fallback
      Since:
        6.0.0

    - #### 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.

      Parameters:
        `fallback` - the value to use when the timeout expires
        `timeoutMillis` - the timeout duration in milliseconds
      Returns:
        a new awaitable that yields either the original result or the fallback
      Since:
        6.0.0

    - #### <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.

      Parameters:
        `source` - the async source to wait for
        `fallback` - the fallback value to use on timeout
        `timeoutMillis` - the timeout duration in milliseconds
      Type Parameters:
        `T` - the result type
      Returns:
        a new awaitable yielding either the original result or the fallback
      Since:
        6.0.0

    - #### public static Awaitable<Void> delay(long milliseconds)

      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

      Parameters:
        `milliseconds` - the delay in milliseconds (must be ≥ 0)
      Returns:
        an awaitable that completes after the delay

    - #### public static Awaitable<Void> delay(long duration, TimeUnit unit)

      Returns an `Awaitable` that completes after the specified delay.

      Parameters:
        `duration` - the delay duration (must be ≥ 0)
        `unit` - the time unit
      Returns:
        an awaitable that completes after the 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. The throwable passed to the function is deeply unwrapped to strip JDK wrapper layers.

      Parameters:
        `fn` - the recovery function
      Returns:
        a new awaitable that recovers from failures

    - #### <T> public static Awaitable<T> failed(Throwable error)

      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"))

      throws:
        NullPointerException if `error` is `null`
      Parameters:
        `error` - the exception to wrap; must not be `null`
      Type Parameters:
        `T` - the nominal result type (never produced, since the awaitable is failed)
      Returns:
        an immediately-failed awaitable

    - #### <T> public static Awaitable<T> first(Object sources)

      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 requests — send the same request to multiple endpoints, use whichever responds first successfully
      - Graceful degradation — try a primary data source, then a fallback, then a cache, accepting the first success
      - Redundant queries — send the same query to different database replicas for improved latency

           // Hedged HTTP request
           def response = await Awaitable.first(
               fetchFromPrimary(),
               fetchFromFallback(),
               fetchFromCache()
           )

      throws:
        IllegalArgumentException if `sources` is `null`, empty, or contains `null` elements
      Parameters:
        `sources` - the awaitables to race for first success; must not be `null`, empty, or contain `null` elements
      Type Parameters:
        `T` - the result type
      Returns:
        an awaitable that resolves with the first successful result
      Since:
        6.0.0
      See Also:
        AsyncSupport#firstAsync(Object...)

    - #### <T> public static Awaitable<T> from(Object source)

      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)

      throws:
        IllegalArgumentException if no adapter supports the source type
      Parameters:
        `source` - the source object; if `null`, returns a completed awaitable with a `null` result
      Type Parameters:
        `T` - the result type
      Returns:
        an awaitable backed by the source
      See Also:
        AwaitableAdapterRegistry.toAwaitable
      Since:
        6.0.0

    - #### public T get()

      Blocks until the computation completes and returns the result.

      throws:
        InterruptedException if the calling thread is interrupted while waiting
      throws:
        ExecutionException if the computation completed exceptionally
      Returns:
        the computed result

    - #### public T get(long timeout, TimeUnit unit)

      Blocks until the computation completes or the timeout expires.

      throws:
        InterruptedException if the calling thread is interrupted while waiting
      throws:
        ExecutionException if the computation completed exceptionally
      throws:
        TimeoutException if the wait timed out
      Parameters:
        `timeout` - the maximum time to wait
        `unit` - the time unit of the timeout argument
      Returns:
        the computed result

    - #### public static Executor getExecutor()

      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.

      Returns:
        the current executor, never `null`
      See Also:
        setExecutor(Executor)

    - #### <T> public static Awaitable<T> go(Supplier<T> supplier)

      Spawns a lightweight task on the default executor.

      Parameters:
        `supplier` - the task body
      Type Parameters:
        `T` - the result type
      Returns:
        an awaitable representing the spawned task
      Since:
        6.0.0

    - #### <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.

      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.

      Parameters:
        `fn` - the handler receiving either the value or the failure
      Type Parameters:
        `U` - the projected result type
      Returns:
        a new awaitable holding the handler's result
      Since:
        6.0.0

    - #### public boolean isCancelled()

      Returns `true` if the computation was cancelled before completing normally.

      Returns:
        `true` if cancelled

    - #### public boolean isCompletedExceptionally()

      Returns `true` if this computation completed exceptionally (including cancellation).

      Returns:
        `true` if completed with an error or cancellation

    - #### public boolean isDone()

      Returns `true` if the computation has completed (normally, exceptionally, or via cancellation).

      Returns:
        `true` if complete

    - #### public static boolean isVirtualThreadsAvailable()

      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.

      Returns:
        `true` if virtual threads are available

    - #### <T> public static Awaitable<T> of(T value)

      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.

      Parameters:
        `value` - the result value (may be `null`)
      Type Parameters:
        `T` - the result type
      Returns:
        a completed awaitable

    - #### 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.

      Parameters:
        `duration` - the timeout duration
        `unit` - the time unit
      Returns:
        a new awaitable with timeout semantics
      Since:
        6.0.0

    - #### <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.

      Parameters:
        `source` - the async source to time out
        `duration` - the timeout duration
        `unit` - the time unit
      Type Parameters:
        `T` - the result type
      Returns:
        a new awaitable with timeout semantics
      Since:
        6.0.0

    - #### public Awaitable<T> orTimeoutMillis(long timeoutMillis)

      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...).

      Parameters:
        `timeoutMillis` - the timeout duration in milliseconds
      Returns:
        a new awaitable with timeout semantics
      Since:
        6.0.0

    - #### <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. 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.

      Parameters:
        `source` - the async source to time out
        `timeoutMillis` - the timeout duration in milliseconds
      Type Parameters:
        `T` - the result type
      Returns:
        a new awaitable with timeout semantics
      Since:
        6.0.0

    - #### public static void setExecutor(Executor executor)

      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.

      Parameters:
        `executor` - the executor to use, or `null` to restore the default executor
      See Also:
        getExecutor()

    - #### <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.

      Parameters:
        `fn` - the mapping function
      Type Parameters:
        `U` - the type of the mapped result
      Returns:
        a new awaitable holding the mapped result

    - #### 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`.

      Useful at API boundaries where you need to attach logging, metrics, or other side effects without blocking for the result.

      Parameters:
        `action` - the side-effecting consumer to invoke on success
      Returns:
        a new awaitable that completes after the action runs
      Since:
        6.0.0

    - #### <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`. This is the monadic `flatMap` operation for awaitables.

      Parameters:
        `fn` - the async mapping function that returns an `Awaitable`
      Type Parameters:
        `U` - the type of the inner awaitable's result
      Returns:
        a new awaitable holding the inner result

    - #### public CompletableFuture<T> toCompletableFuture()

      Converts this `Awaitable` to a JDK CompletableFuture for interoperability with APIs that require it.

      Returns:
        a `CompletableFuture` representing this computation

    - #### 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.

      The supplied throwable is transparently unwrapped so handlers see the original failure rather than ExecutionException / CompletionException wrappers.

      Parameters:
        `action` - the completion callback receiving the result or failure
      Returns:
        a new awaitable that completes with the original result
      Since:
        6.0.0

    - #### <T> public static T withScope(Function<AsyncScope, T> body)

      Convenience delegate to AsyncScope.withScope. Creates a structured concurrency scope, executes the body within it, and ensures all child tasks complete before returning.

      Parameters:
        `body` - the function receiving the scope
      Type Parameters:
        `T` - the result type
      Returns:
        the body's return value
      See Also:
        AsyncScope.withScope
      Since:
        6.0.0