Package: groovy.concurrent

## [Java] Interface AsyncScope

-     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
       }

  See Also:
    Awaitable
  Since:
    6.0.0

- - ### Methods Summary

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

  - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `interface AutoCloseable` | `close`

- - ### Method Detail

    - #### <T> public 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.

      throws:
        IllegalStateException if the scope has already been closed
      Parameters:
        `supplier` - the task body to execute
      Type Parameters:
        `T` - the result type
      Returns:
        an Awaitable representing the child task

    - #### public void cancelAll()

      Cancels all child tasks.

    - #### public 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.

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

      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.

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

    - #### <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. 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)]
           }
           }

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

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

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

    - #### <T> public static T withScope(Duration timeout, Function<AsyncScope, T> body)

      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.

      throws:
        TimeoutException if the timeout expires
      Parameters:
        `timeout` - the maximum duration for the scope
        `body` - the function to execute within the scope
      Type Parameters:
        `T` - the result type
      Returns:
        the body's return value
      Since:
        6.0.0

    - #### <T> public static T withScope(Executor executor, Duration timeout, Function<AsyncScope, T> body)

      Creates a scope with the given executor and a timeout.

      throws:
        TimeoutException if the timeout expires
      Parameters:
        `executor` - the executor for child tasks
        `timeout` - the maximum duration for the scope
        `body` - the function to execute within the scope
      Type Parameters:
        `T` - the result type
      Returns:
        the body's return value
      Since:
        6.0.0