Package org.apache.groovy.runtime.async
Class AsyncSupport
java.lang.Object
org.apache.groovy.runtime.async.AsyncSupport
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 Summary
Modifier and TypeMethodDescriptionstatic <T> List<T>Waits for all given sources to complete, returning their results in order.Non-blocking variant ofall(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 ofAwaitResultwithout throwing.static Awaitable<List<AwaitResult<Object>>>allSettledAsync(Object... sources) Non-blocking variant ofallSettled(java.lang.Object...)— returns an Awaitable.static <T> TReturns the result of the first source to complete (success or failure).static <T> Awaitable<T>Non-blocking variant ofany(java.lang.Object...)— returns an Awaitable.static <T> Awaitable<T>Executes the given closure asynchronously using the default executor.static <T> Iterable<T>asyncGenerator(Closure<?> closure) Starts a generator immediately, returning anIterablebacked by aGeneratorBridge.static <T> TAwaits the result of anAwaitable.static <T> TAwaits an arbitrary object by adapting it viaAwaitable.from(Object).static <T> Tawait(CompletableFuture<T> future) Awaits aCompletableFutureusing non-interruptiblejoin().static <T> Tawait(CompletionStage<T> stage) Awaits aCompletionStageby converting to CompletableFuture.static <T> TAwaits aFuture.static voidcloseIterable(Object source) Closes a source if it implementsCloseableorAutoCloseable.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.Creates a new defer scope (LIFO stack of cleanup actions).static voidRegisters a deferred action in the given scope.delay(long millis) Returns an Awaitable that completes after the specified delay.Delay with explicit time unit.static <T> Awaitable<T>executeAsync(Closure<T> closure, Executor executor) Executes the given closure asynchronously on the specified executor, returning anAwaitable.static voidexecuteDeferScope(Deque<Closure<?>> scope) Executes all deferred actions in LIFO order.static <T> TReturns the result of the first source to complete successfully.static <T> Awaitable<T>firstAsync(Object... sources) Non-blocking variant offirst(java.lang.Object...)— returns an Awaitable.static ExecutorReturns the current executor used for async tasks.static <T> Awaitable<T>Lightweight task spawn.static booleanReturnstrueif running on JDK 21+ with virtual thread support.static <T> Awaitable<T>Wraps a source with a timeout.static <T> Awaitable<T>orTimeoutMillis(Object source, long millis) Convenience: timeout in milliseconds.static voidResets the executor to the default (virtual threads on JDK 21+, cached pool otherwise).static voidsetExecutor(Executor executor) Sets the executor used for async tasks.static <T> Iterable<T>toIterable(Object source) Converts an arbitrary source to anIterablefor use infor awaitloops.static ThrowableWraps a closure so that each invocation executes the body asynchronously and returns anAwaitable.wrapAsyncGenerator(Closure<?> closure) Wraps a generator closure so that each invocation returns anIterablebacked by aGeneratorBridge.static voidyieldReturn(Object bridge, Object value) Called by compiler-generated code foryield return exprinside an async generator closure.
-
Method Details
-
isVirtualThreadsAvailable
public static boolean isVirtualThreadsAvailable()Returnstrueif running on JDK 21+ with virtual thread support. -
getExecutor
Returns the current executor used for async tasks. -
setExecutor
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
Awaits the result of anAwaitable. Blocks the calling thread until the computation completes. The original exception is rethrown transparently. -
await
Awaits aCompletableFutureusing non-interruptiblejoin(). -
await
Awaits aCompletionStageby converting to CompletableFuture. -
await
Awaits aFuture. Delegates to the CF overload if applicable. -
await
Awaits an arbitrary object by adapting it viaAwaitable.from(Object). This is the fallback overload called by compiler-generated await expressions. -
executeAsync
Executes the given closure asynchronously on the specified executor, returning anAwaitable. -
async
Executes the given closure asynchronously using the default executor. -
go
Lightweight task spawn. Executes the closure asynchronously using the default executor. -
wrapAsync
Wraps a closure so that each invocation executes the body asynchronously and returns anAwaitable. This is the runtime entry point for theasync { ... }expression syntax.def task = async { expensiveWork() } def result = await task() // explicit call required -
yieldReturn
Called by compiler-generated code foryield return exprinside 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
-
wrapAsyncGenerator
Wraps a generator closure so that each invocation returns anIterablebacked by aGeneratorBridge. The generator runs on a background thread and yields values via the bridge.This is the runtime entry point for
async { ... yield return ... }expressions that containyield return.- Type Parameters:
T- the element type- Parameters:
closure- the generator closure; receives a GeneratorBridge as first parameter- Returns:
- a closure that produces an Iterable when called
-
asyncGenerator
Starts a generator immediately, returning anIterablebacked by aGeneratorBridge. This is the runtime entry point forasync { ... yield return ... }expressions.- Type Parameters:
T- the element type- Parameters:
closure- the generator closure; receives a GeneratorBridge as first parameter- Returns:
- an Iterable that yields values from the generator
-
toIterable
Converts an arbitrary source to anIterablefor use infor awaitloops. Handles arrays, collections, iterables, iterators, and adapter-supported types. The returned iterable may block onnext()for async sources.- Type Parameters:
T- the element type- Parameters:
source- the source to convert- Returns:
- an iterable
-
closeIterable
Closes a source if it implementsCloseableorAutoCloseable. Called by compiler-generated finally block infor awaitloops. -
all
Waits for all given sources to complete, returning their results in order. Multi-argawait(a, b, c)desugars to this. -
any
Returns the result of the first source to complete (success or failure). -
first
Returns the result of the first source to complete successfully. Only fails when all sources fail. -
allSettled
Waits for all sources to settle (succeed or fail), returning a list ofAwaitResultwithout throwing. -
allAsync
Non-blocking variant ofall(java.lang.Object...)— returns an Awaitable. -
anyAsync
Non-blocking variant ofany(java.lang.Object...)— returns an Awaitable. -
firstAsync
Non-blocking variant offirst(java.lang.Object...)— returns an Awaitable. -
allSettledAsync
Non-blocking variant ofallSettled(java.lang.Object...)— returns an Awaitable. -
delay
Returns an Awaitable that completes after the specified delay. -
delay
Delay with explicit time unit. -
orTimeout
Wraps a source with a timeout. If the source does not complete within the specified time, the returned Awaitable fails withTimeoutException. -
orTimeoutMillis
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
Convenience: timeout in milliseconds. -
createDeferScope
Creates a new defer scope (LIFO stack of cleanup actions). Called by compiler-generated code at the start of closures containingdeferstatements. -
defer
Registers a deferred action in the given scope. Actions execute in LIFO order whenexecuteDeferScope(java.util.Deque<groovy.lang.Closure<?>>)is called (in the finally block). -
executeDeferScope
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. -
unwrap
-