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 contains the actual implementation invoked by compiler-generated code. User code should prefer the static methods on Awaitable for combinators and configuration.

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 at any time via setExecutor(java.util.concurrent.Executor).

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

Since:
6.0.0
See Also:
  • 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.
    • resetExecutor

      public static void resetExecutor()
      Resets the executor to the default (virtual threads on JDK 21+, cached pool otherwise).
    • await

      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

      public static <T> T await(CompletableFuture<T> future)
      Awaits a CompletableFuture using non-interruptible join().
    • await

      public static <T> T await(CompletionStage<T> stage)
      Awaits a CompletionStage by converting to CompletableFuture.
    • await

      public static <T> T await(Future<T> future)
      Awaits a Future. Delegates to the CF overload if applicable.
    • await

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

      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. Executes the supplier asynchronously using the default executor.
    • createDeferScope

      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

      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

      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

      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

      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

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