Package groovy.concurrent

# Interface AsyncScope

All Superinterfaces:
  `AutoCloseable`

All Known Implementing Classes:
  `DefaultAsyncScope`

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:

- Orphaned tasks that outlive their logical parent
- Resource leaks from uncollected async work
- Silent failures from unobserved exceptions

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

Since:
  6.0.0
See Also:
  - `Awaitable`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `<T> Awaitable<T>`
  `async(Supplier<T> supplier)`
  Launches a child task within this scope.
  `void`
  `cancelAll()`
  Cancels all child tasks.
  `void`
  `close()`
  Closes the scope, waiting for all child tasks to complete.
  `static AsyncScope`
  `create()`
  Creates a new scope with the default executor and fail-fast enabled.
  `static AsyncScope`
  `create(Executor executor)`
  Creates a new scope with the given executor and fail-fast enabled.
  `static AsyncScope`
  `create(Executor executor, boolean failFast)`
  Creates a new scope with the given executor and failure policy.
  `static AsyncScope`
  `current()`
  Returns the scope currently bound to this thread, or `null`.
  `int`
  `getChildCount()`
  Returns the number of tracked child tasks (including completed ones that have not yet been pruned).
  `AsyncScope`
  `getParent()`
  Returns the parent scope, or `null` if this is a root scope.
  `static <T> T`
  `withCurrent(AsyncScope scope, Supplier<T> supplier)`
  Executes the supplier with the given scope installed as current, restoring the previous binding afterwards.
  `static <T> T`
  `withScope(Duration timeout, Function<AsyncScope,T> body)`
  Creates a scope with a timeout.
  `static <T> T`
  `withScope(Executor executor, Duration timeout, Function<AsyncScope,T> body)`
  Creates a scope with the given executor and a timeout.
  `static <T> 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.
  `static <T> T`
  `withScope(Function<AsyncScope,T> body)`
  Creates a scope, executes the body within it, and ensures the scope is closed on exit.

- ## Method Details

  - ### async

    <T> Awaitable<T> async(Supplier<T> supplier)
    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.
    Type Parameters:
      `T` - the result type
    Parameters:
      `supplier` - the task body to execute
    Returns:
      an `Awaitable` representing the child task
    Throws:
      `IllegalStateException` - if the scope has already been closed

  - ### getParent

    AsyncScope getParent()
    Returns the parent scope, or `null` if this is a root scope.

    When a scope is created inside another scope (via `withScope(java.util.function.Function<groovy.concurrent.AsyncScope, T>)`), the outer scope becomes the parent. Cancelling a parent scope propagates cancellation to all child scopes.

    Returns:
      the parent scope, or `null`
    Since:
      6.0.0

  - ### getChildCount

    int getChildCount()
    Returns the number of tracked child tasks (including completed ones that have not yet been pruned).

  - ### cancelAll

    void cancelAll()
    Cancels all child tasks.

  - ### close

    void close()
    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.
    Specified by:
      `close` in interface `AutoCloseable`

  - ### current

    static AsyncScope current()
    Returns the scope currently bound to this thread, or `null`.

  - ### withCurrent

    static <T> T withCurrent(AsyncScope scope, Supplier<T> supplier)
    Executes the supplier with the given scope installed as current, restoring the previous binding afterwards.

  - ### withScope

    static <T> T withScope(Function<AsyncScope,T> body)
    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)]
         }

    Type Parameters:
      `T` - the result type
    Parameters:
      `body` - the function to execute within the scope
    Returns:
      the body's return value

  - ### withScope

    static <T> 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.
    Type Parameters:
      `T` - the result type
    Parameters:
      `executor` - the executor for child tasks
      `body` - the function to execute within the scope
    Returns:
      the body's return value

  - ### withScope

    static <T> T withScope(Duration timeout, Function<AsyncScope,T> body) throws TimeoutException
    Creates 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`.
    Type Parameters:
      `T` - the result type
    Parameters:
      `timeout` - the maximum duration for the scope
      `body` - the function to execute within the scope
    Returns:
      the body's return value
    Throws:
      `TimeoutException` - if the timeout expires
    Since:
      6.0.0

  - ### withScope

    static <T> T withScope(Executor executor, Duration timeout, Function<AsyncScope,T> body) throws TimeoutException
    Creates a scope with the given executor and a timeout.
    Type Parameters:
      `T` - the result type
    Parameters:
      `executor` - the executor for child tasks
      `timeout` - the maximum duration for the scope
      `body` - the function to execute within the scope
    Returns:
      the body's return value
    Throws:
      `TimeoutException` - if the timeout expires
    Since:
      6.0.0

  - ### create

    static AsyncScope create()
    Creates a new scope with the default executor and fail-fast enabled.

  - ### create

    static AsyncScope create(Executor executor)
    Creates a new scope with the given executor and fail-fast enabled.

  - ### create

    static AsyncScope create(Executor executor, boolean failFast)
    Creates a new scope with the given executor and failure policy.