Package org.apache.groovy.runtime.async

# Class AsyncSupport

java.lang.Object
org.apache.groovy.runtime.async.AsyncSupport

public class AsyncSupport extends Object
Internal runtime support for the `async`/`await`/`defer` language features.

This class is the entry point invoked by compiler-generated code and also exposes the combinator and configuration surface used by `Awaitable`. Combinator algorithms live in `AwaitCombinators`; executor/scheduler configuration lives in `AsyncExecutors`.

Thread pool configuration:

- On JDK 21+ the default executor is a virtual-thread-per-task executor. Virtual threads make blocking within `await()` essentially free.
- On JDK 17-20 the fallback is a cached daemon thread pool whose maximum size is controlled by the system property `groovy.async.parallelism` (default: `256`).
- The executor can be overridden via `setExecutor(java.util.concurrent.Executor)`; pass `null` to restore the platform default.

Exception handling follows a transparency principle: the original exception is rethrown without being wrapped.

Since:
  6.0.0
See Also:
  - `Awaitable`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static <T> List<T>`
  `all(Object... sources)`
  Waits for all given sources to complete, returning their results in order.
  `static Awaitable<List<Object>>`
  `allAsync(Object... sources)`
  Non-blocking variant of `all(java.lang.Object...)` — returns an Awaitable.
  `static List<AwaitResult<Object>>`
  `allSettled(Object... sources)`
  Waits for all sources to settle (succeed or fail), returning a list of `AwaitResult` without throwing.
  `static Awaitable<List<AwaitResult<Object>>>`
  `allSettledAsync(Object... sources)`
  Non-blocking variant of `allSettled(java.lang.Object...)` — returns an Awaitable.
  `static <T> T`
  `any(Object... sources)`
  Returns the result of the first source to complete (success or failure).
  `static <T> Awaitable<T>`
  `anyAsync(Object... sources)`
  Non-blocking variant of `any(java.lang.Object...)` — returns an Awaitable.
  `static <T> Awaitable<T>`
  `async(Supplier<T> supplier)`
  Executes the given supplier asynchronously using the default executor.
  `static <T> Iterable<T>`
  `asyncGenerator(Consumer<Object> body)`
  Starts a generator immediately, returning an `Iterable` backed by a `GeneratorBridge`.
  `static <T> T`
  `await(Awaitable<T> awaitable)`
  Awaits the result of an `Awaitable`.
  `static <T> T`
  `await(Object source)`
  Awaits an arbitrary object by adapting it via `Awaitable.from(Object)`.
  `static <T> T`
  `await(CompletableFuture<T> future)`
  Awaits a `CompletableFuture` using non-interruptible `join()`.
  `static <T> T`
  `await(CompletionStage<T> stage)`
  Awaits a `CompletionStage` by converting to CompletableFuture.
  `static <T> T`
  `await(Future<T> future)`
  Awaits a `Future`.
  `static void`
  `closeIterable(Object source)`
  Closes a source if it implements `Closeable` or `AutoCloseable`.
  `static <T> Awaitable<T>`
  `completeOnTimeout(Object source, T fallback, long timeout, TimeUnit unit)`
  Wraps a source with a timeout that uses a fallback value instead of throwing.
  `static <T> Awaitable<T>`
  `completeOnTimeoutMillis(Object source, T fallback, long millis)`
  Convenience: timeout in milliseconds.
  `static Deque<Callable<?>>`
  `createDeferScope()`
  Creates a new defer scope (LIFO stack of cleanup actions).
  `static void`
  `defer(Deque<Callable<?>> scope, Callable<?> action)`
  Registers a deferred action in the given scope.
  `static Awaitable<Void>`
  `delay(long millis)`
  Returns an Awaitable that completes after the specified delay.
  `static Awaitable<Void>`
  `delay(long duration, TimeUnit unit)`
  Delay with explicit time unit.
  `static <T> Awaitable<T>`
  `executeAsync(Supplier<T> supplier, Executor executor)`
  Executes the given supplier asynchronously on the specified executor, returning an `Awaitable`.
  `static void`
  `executeDeferScope(Deque<Callable<?>> scope)`
  Executes all deferred actions in LIFO order.
  `static <T> T`
  `first(Object... sources)`
  Returns the result of the first source to complete successfully.
  `static <T> Awaitable<T>`
  `firstAsync(Object... sources)`
  Non-blocking variant of `first(java.lang.Object...)` — returns an Awaitable.
  `static Executor`
  `getExecutor()`
  Returns the current executor used for async tasks.
  `static ScheduledExecutorService`
  `getScheduler()`
  Returns the shared scheduler for delays, timeouts, and scope deadlines.
  `static <T> Awaitable<T>`
  `go(Supplier<T> supplier)`
  Lightweight task spawn.
  `static boolean`
  `isVirtualThreadsAvailable()`
  Returns `true` if running on JDK 21+ with virtual thread support.
  `static <T> Awaitable<T>`
  `orTimeout(Object source, long timeout, TimeUnit unit)`
  Wraps a source with a timeout.
  `static <T> Awaitable<T>`
  `orTimeoutMillis(Object source, long millis)`
  Convenience: timeout in milliseconds.
  `static void`
  `resetExecutor()`
  Resets the executor to the platform default.
  `static void`
  `setExecutor(Executor executor)`
  Sets the executor used for async tasks.
  `static <T> Iterable<T>`
  `toIterable(Object source)`
  Converts an arbitrary source to an `Iterable` for use in `for await` loops.
  `static Throwable`
  `unwrap(Throwable t)`
  Strips JDK wrapper layers (`CompletionException`, `ExecutionException`, `InvocationTargetException`, `UndeclaredThrowableException`) to expose the original cause.
  `static CompletionException`
  `wrapForFuture(Throwable t)`
  `static void`
  `yieldReturn(Object bridge, Object value)`
  Called by compiler-generated code for `yield return expr` inside an async generator closure.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Method Details

  - ### getScheduler

    public static ScheduledExecutorService getScheduler()
    Returns the shared scheduler for delays, timeouts, and scope deadlines.

  - ### isVirtualThreadsAvailable

    public static boolean isVirtualThreadsAvailable()
    Returns `true` if running on JDK 21+ with virtual thread support.

  - ### getExecutor

    public static Executor getExecutor()
    Returns the current executor used for async tasks.

  - ### setExecutor

    public static void setExecutor(Executor executor)
    Sets the executor used for async tasks.

    Pass `null` to restore the platform default (virtual threads on JDK 21+, cached daemon pool otherwise). The change takes effect for subsequent `async` launches; in-flight tasks keep the executor that started them.

    Parameters:
      `executor` - the executor to use, or `null` to reset

  - ### resetExecutor

    public static void resetExecutor()
    Resets the executor to the platform default. Equivalent to `setExecutor(null)`.

  - ### await

    @GroovyABI(since="6.0.0") public static <T> T await(Awaitable<T> awaitable)
    Awaits the result of an `Awaitable`. Blocks the calling thread until the computation completes. The original exception is rethrown transparently.

  - ### await

    @GroovyABI(since="6.0.0") public static <T> T await(CompletableFuture<T> future)
    Awaits a `CompletableFuture` using non-interruptible `join()`.

  - ### await

    @GroovyABI(since="6.0.0") public static <T> T await(CompletionStage<T> stage)
    Awaits a `CompletionStage` by converting to CompletableFuture.

  - ### await

    @GroovyABI(since="6.0.0") public static <T> T await(Future<T> future)
    Awaits a `Future`. Delegates to the CF overload if applicable.

  - ### await

    @GroovyABI(since="6.0.0") public static <T> T await(Object source)
    Awaits an arbitrary object by adapting it via `Awaitable.from(Object)`.

    This is the fallback overload called by compiler-generated `await` expressions. The compiler inserts a cast to `Object` so that overload resolution does not have to choose among `Awaitable`, `CompletionStage`, and `Future` when a value implements more than one of them (e.g. `CompletableFuture`).

  - ### executeAsync

    public static <T> Awaitable<T> executeAsync(Supplier<T> supplier, Executor executor)
    Executes the given supplier asynchronously on the specified executor, returning an `Awaitable`.

  - ### async

    @GroovyABI(since="6.0.0") public static <T> Awaitable<T> async(Supplier<T> supplier)
    Executes the given supplier asynchronously using the default executor.

  - ### go

    public static <T> Awaitable<T> go(Supplier<T> supplier)
    Lightweight task spawn. Alias of `async(Supplier)` for Go-style ergonomics; semantics are identical.

  - ### createDeferScope

    @GroovyABI(since="6.0.0") public static Deque<Callable<?>> createDeferScope()
    Creates a new defer scope (LIFO stack of cleanup actions). Called by compiler-generated code at the start of closures containing `defer` statements.

  - ### defer

    @GroovyABI(since="6.0.0") public static void defer(Deque<Callable<?>> scope, Callable<?> action)
    Registers a deferred action in the given scope. Actions execute in LIFO order when `executeDeferScope(java.util.Deque<java.util.concurrent.Callable<?>>)` is called (in the finally block).

  - ### executeDeferScope

    public static void executeDeferScope(Deque<Callable<?>> scope)
    Executes all deferred actions in LIFO order. If multiple actions throw, subsequent exceptions are added as suppressed. If a deferred action returns a Future/Awaitable, the result is awaited before continuing.

  - ### yieldReturn

    @GroovyABI(since="6.0.0") public static void yieldReturn(Object bridge, Object value)
    Called by compiler-generated code for `yield return expr` inside an async generator closure. Delegates to the bridge's yield method.
    Parameters:
      `bridge` - the GeneratorBridge instance (injected as synthetic parameter)
      `value` - the value to yield

  - ### asyncGenerator

    @GroovyABI(since="6.0.0") public static <T> Iterable<T> asyncGenerator(Consumer<Object> body)
    Starts a generator immediately, returning an `Iterable` backed by a `GeneratorBridge`. The consumer receives the bridge as its argument and should call `yieldReturn(java.lang.Object, java.lang.Object)` to produce values.

    This is the runtime entry point for `async { ... yield return ... }` expressions. The compiler generates a closure that SAM-coerces to `Consumer<Object>`.

    Type Parameters:
      `T` - the element type
    Parameters:
      `body` - the generator body; receives a `GeneratorBridge`
    Returns:
      an Iterable that yields values from the generator

  - ### toIterable

    @GroovyABI(since="6.0.0") public static <T> Iterable<T> toIterable(Object source)
    Converts an arbitrary source to an `Iterable` for use in `for await` loops. Handles arrays, collections, iterables, iterators, and adapter-supported types. The returned iterable may block on `next()` for async sources.
    Type Parameters:
      `T` - the element type
    Parameters:
      `source` - the source to convert
    Returns:
      an iterable

  - ### closeIterable

    @GroovyABI(since="6.0.0") public static void closeIterable(Object source)
    Closes a source if it implements `Closeable` or `AutoCloseable`. Called by compiler-generated finally block in `for await` loops. Cleanup exceptions are swallowed so they cannot mask the original loop error; prefer robust `close()` implementations.

  - ### all

    public static <T> List<T> all(Object... sources)
    Waits for all given sources to complete, returning their results in order. Multi-arg `await(a, b, c)` desugars to the non-blocking `allAsync(Object...)` form, then awaits it.

  - ### any

    public static <T> T any(Object... sources)
    Returns the result of the first source to complete (success or failure).

  - ### first

    public static <T> T first(Object... sources)
    Returns the result of the first source to complete successfully. Only fails when all sources fail (aggregate `CompletionException`; `await` transparency rethrows the cause).

  - ### allSettled

    public static List<AwaitResult<Object>> allSettled(Object... sources)
    Waits for all sources to settle (succeed or fail), returning a list of `AwaitResult` without throwing.

  - ### allAsync

    public static Awaitable<List<Object>> allAsync(Object... sources)
    Non-blocking variant of `all(java.lang.Object...)` — returns an Awaitable.

  - ### anyAsync

    public static <T> Awaitable<T> anyAsync(Object... sources)
    Non-blocking variant of `any(java.lang.Object...)` — returns an Awaitable.

  - ### firstAsync

    public static <T> Awaitable<T> firstAsync(Object... sources)
    Non-blocking variant of `first(java.lang.Object...)` — returns an Awaitable.

  - ### allSettledAsync

    public static Awaitable<List<AwaitResult<Object>>> allSettledAsync(Object... sources)
    Non-blocking variant of `allSettled(java.lang.Object...)` — returns an Awaitable.

  - ### delay

    public static Awaitable<Void> delay(long millis)
    Returns an Awaitable that completes after the specified delay.

  - ### delay

    public static Awaitable<Void> delay(long duration, TimeUnit unit)
    Delay with explicit time unit.

  - ### orTimeout

    public static <T> Awaitable<T> orTimeout(Object source, long timeout, TimeUnit unit)
    Wraps a source with a timeout. If the source does not complete within the specified time, the returned Awaitable fails with `TimeoutException` and the underlying computation is cancelled.

  - ### orTimeoutMillis

    public static <T> Awaitable<T> orTimeoutMillis(Object source, long millis)
    Convenience: timeout in milliseconds.

  - ### completeOnTimeout

    public static <T> Awaitable<T> completeOnTimeout(Object source, T fallback, long timeout, TimeUnit unit)
    Wraps a source with a timeout that uses a fallback value instead of throwing. On timeout the underlying computation is cancelled.

  - ### completeOnTimeoutMillis

    public static <T> Awaitable<T> completeOnTimeoutMillis(Object source, T fallback, long millis)
    Convenience: timeout in milliseconds.

  - ### wrapForFuture

    public static CompletionException wrapForFuture(Throwable t)

  - ### unwrap

    public static Throwable unwrap(Throwable t)
    Strips JDK wrapper layers (`CompletionException`, `ExecutionException`, `InvocationTargetException`, `UndeclaredThrowableException`) to expose the original cause.