public interface AsyncScope
extends AutoCloseable
A structured concurrency scope that ensures all child tasks complete (or are cancelled) before the scope exits.
AsyncScope provides a bounded lifetime for async tasks,
following the structured concurrency model. Unlike
fire-and-forget async { ... }, tasks launched within a scope
are guaranteed to complete before the scope closes. This prevents:
By default, the scope uses a fail-fast policy: when any child task completes exceptionally, all sibling tasks are cancelled immediately. The first failure becomes the primary exception; subsequent failures are added as suppressed exceptions.
def results = AsyncScope.withScope { scope ->
def userTask = scope.async { fetchUser(id)
def orderTask = scope.async { fetchOrders(id) }
return [user: await(userTask), orders: await(orderTask)]
}
// Both tasks guaranteed complete here
}
| Type Params | Return Type | Name and description |
|---|---|---|
<T> |
public Awaitable<T> |
async(Supplier<T> supplier)Launches a child task within this scope. |
|
public void |
cancelAll()Cancels all child tasks. |
|
public void |
close()Closes the scope, waiting for all child tasks to complete. |
|
public static AsyncScope |
create()Creates a new scope with the default executor and fail-fast enabled. |
|
public static AsyncScope |
create(Executor executor)Creates a new scope with the given executor and fail-fast enabled. |
|
public static AsyncScope |
create(Executor executor, boolean failFast)Creates a new scope with the given executor and failure policy. |
|
public static AsyncScope |
current()Returns the scope currently bound to this thread, or null. |
|
public int |
getChildCount()Returns the number of tracked child tasks (including completed ones that have not yet been pruned). |
|
public AsyncScope |
getParent()Returns the parent scope, or null if this is a root scope. |
<T> |
public static T |
withCurrent(AsyncScope scope, Supplier<T> supplier)Executes the supplier with the given scope installed as current, restoring the previous binding afterwards. |
<T> |
public static T |
withScope(Function<AsyncScope, T> body)Creates a scope, executes the body within it, and ensures the scope is closed on exit. |
<T> |
public static T |
withScope(Executor executor, Function<AsyncScope, T> body)Creates a scope with the given executor, executes the body, and ensures the scope is closed on exit. |
<T> |
public static T |
withScope(Duration timeout, Function<AsyncScope, T> body)Creates a scope with a timeout. |
<T> |
public static T |
withScope(Executor executor, Duration timeout, Function<AsyncScope, T> body)Creates a scope with the given executor and a timeout. |
| Methods inherited from class | Name |
|---|---|
interface AutoCloseable |
close |
Launches a child task within this scope. The task's lifetime is bound to the scope: when the scope is closed, all incomplete child tasks are cancelled.
supplier - the task body to executeT - the result typeCancels all child tasks.
Closes the scope, waiting for all child tasks to complete. If any child failed and fail-fast is enabled, remaining children are cancelled and the first failure is rethrown.
Creates a new scope with the default executor and fail-fast enabled.
Creates a new scope with the given executor and fail-fast enabled.
Creates a new scope with the given executor and failure policy.
Returns the scope currently bound to this thread, or null.
Returns the number of tracked child tasks (including completed ones that have not yet been pruned).
Returns the parent scope, or null if this is a root scope.
When a scope is created inside another scope (via withScope), the outer scope becomes the parent. Cancelling a parent scope propagates cancellation to all child scopes.
nullExecutes the supplier with the given scope installed as current, restoring the previous binding afterwards.
Creates a scope, executes the body within it, and ensures the scope is closed on exit. The body receives the scope as its argument for launching child tasks.
// Java:
var result = AsyncScope.withScope(scope -> {
var a = scope.async(() -> computeA());
var b = scope.async(() -> computeB());
return List.of(AsyncSupport.await(a), AsyncSupport.await(b));
);
// Groovy (Closure overload added via extension method):
def result = AsyncScope.withScope { scope ->
def a = scope.async { computeA() }
def b = scope.async { computeB() }
return [await(a), await(b)]
}
}
body - the function to execute within the scopeT - the result typeCreates a scope with the given executor, executes the body, and ensures the scope is closed on exit.
executor - the executor for child tasksbody - the function to execute within the scopeT - the result typeCreates a scope with a timeout. If the body does not complete within the specified duration, all child tasks are cancelled and the scope throws TimeoutException.
timeout - the maximum duration for the scopebody - the function to execute within the scopeT - the result typeCreates a scope with the given executor and a timeout.
executor - the executor for child taskstimeout - the maximum duration for the scopebody - the function to execute within the scopeT - the result type