Package org.apache.groovy.runtime.async

# Class GroovyPromise<T>

java.lang.Object
org.apache.groovy.runtime.async.GroovyPromise<T>

Type Parameters:
  `T` - the result type

All Implemented Interfaces:
  `Awaitable<T>`

public class GroovyPromise<T> extends Object implements Awaitable<T>
Default `Awaitable` implementation backed by a `CompletableFuture`.

This is the concrete type returned by `async` methods. It delegates all operations to an underlying `CompletableFuture` while keeping the public API limited to the `Awaitable` contract, thereby decoupling user code from JDK-specific async APIs.

This class is an internal implementation detail and should not be referenced directly by user code. Use the `Awaitable` interface instead.

Since:
  6.0.0
See Also:
  - `Awaitable`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `GroovyPromise(CompletableFuture<T> future)`
  Creates a new `GroovyPromise` wrapping the given `CompletableFuture`.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `cancel()`
  Attempts to cancel this computation.
  `Awaitable<T>`
  `exceptionally(Function<Throwable,? extends T> fn)`
  Returns a new `Awaitable` that, if this one completes exceptionally, applies the given function to the exception to produce a recovery value.
  `T`
  `get()`
  Blocks until the computation completes and returns the result.
  `T`
  `get(long timeout, TimeUnit unit)`
  Blocks until the computation completes or the timeout expires.
  `boolean`
  `isCancelled()`
  Returns `true` if the computation was cancelled before completing normally.
  `boolean`
  `isCompletedExceptionally()`
  Returns `true` if this computation completed exceptionally (including cancellation).
  `boolean`
  `isDone()`
  Returns `true` if the computation has completed (normally, exceptionally, or via cancellation).
  `static <T> GroovyPromise<T>`
  `of(CompletableFuture<T> future)`
  Creates a `GroovyPromise` wrapping the given `CompletableFuture`.
  `<U> Awaitable<U>`
  `then(Function<? super T,? extends U> fn)`
  Returns a new `Awaitable` whose result is obtained by applying the given function to this awaitable's result when it completes.
  `<U> Awaitable<U>`
  `thenCompose(Function<? super T,? extends Awaitable<U>> fn)`
  Returns a new `Awaitable` produced by applying the given async function to this awaitable's result, flattening the nested `Awaitable`.
  `CompletableFuture<T>`
  `toCompletableFuture()`
  Converts this `Awaitable` to a JDK `CompletableFuture` for interoperability with APIs that require it.
  `String`
  `toString()`
  Returns a human-readable representation showing the promise state: `GroovyPromise{pending}`, `GroovyPromise{completed}`, or `GroovyPromise{failed}`.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

  ### Methods inherited from interface groovy.concurrent.Awaitable

  `completeOnTimeout, completeOnTimeoutMillis, handle, orTimeout, orTimeoutMillis, thenAccept, whenComplete`

- ## Constructor Details

  - ### GroovyPromise

    public GroovyPromise(CompletableFuture<T> future)
    Creates a new `GroovyPromise` wrapping the given `CompletableFuture`.
    Parameters:
      `future` - the backing future; must not be `null`
    Throws:
      `NullPointerException` - if `future` is `null`

- ## Method Details

  - ### of

    public static <T> GroovyPromise<T> of(CompletableFuture<T> future)
    Creates a `GroovyPromise` wrapping the given `CompletableFuture`.

    This is a convenience factory that delegates to `GroovyPromise(CompletableFuture)`.

    Type Parameters:
      `T` - the result type
    Parameters:
      `future` - the backing future; must not be `null`
    Returns:
      a new `GroovyPromise` wrapping `future`
    Throws:
      `NullPointerException` - if `future` is `null`

  - ### get

    public T get() throws InterruptedException, ExecutionException
    Blocks until the computation completes and returns the result.

    Includes a synchronous completion fast-path: if the underlying `CompletableFuture` is already done, the result is extracted via `CompletableFuture.join()` which avoids the full park/unpark machinery of `CompletableFuture.get()`. This optimisation provides a synchronous completion fast-path and eliminates unnecessary thread state transitions on the hot path where async operations complete before being awaited.

    If the future was cancelled, the original `CancellationException` is unwrapped from the JDK 23+ wrapper for cross-version consistency.

    Specified by:
      `get` in interface `Awaitable<T>`
    Returns:
      the computed result
    Throws:
      `InterruptedException` - if the calling thread is interrupted while waiting
      `ExecutionException` - if the computation completed exceptionally

  - ### get

    public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
    Blocks until the computation completes or the timeout expires.

    Includes a synchronous completion fast-path for already-done futures, consistent with the zero-argument `get()` overload. Unwraps JDK 23+ `CancellationException` wrappers for consistency.

    Specified by:
      `get` in interface `Awaitable<T>`
    Parameters:
      `timeout` - the maximum time to wait
      `unit` - the time unit of the timeout argument
    Returns:
      the computed result
    Throws:
      `InterruptedException` - if the calling thread is interrupted while waiting
      `ExecutionException` - if the computation completed exceptionally
      `TimeoutException` - if the wait timed out

  - ### isDone

    public boolean isDone()
    Returns `true` if the computation has completed (normally, exceptionally, or via cancellation).
    Specified by:
      `isDone` in interface `Awaitable<T>`
    Returns:
      `true` if complete

  - ### cancel

    public boolean cancel()
    Attempts to cancel this computation. Delegates to `CompletableFuture.cancel(true)`.

    Note: `CompletableFuture` cancellation sets the future's state to cancelled but does not reliably interrupt the underlying thread. Async work already in progress may continue running in the background. For cooperative cancellation, check `Thread.isInterrupted()` in long-running async bodies.

    Specified by:
      `cancel` in interface `Awaitable<T>`
    Returns:
      `true` if the future was successfully cancelled

  - ### isCancelled

    public boolean isCancelled()
    Returns `true` if the computation was cancelled before completing normally.
    Specified by:
      `isCancelled` in interface `Awaitable<T>`
    Returns:
      `true` if cancelled

  - ### isCompletedExceptionally

    public boolean isCompletedExceptionally()
    Returns `true` if this computation completed exceptionally (including cancellation).
    Specified by:
      `isCompletedExceptionally` in interface `Awaitable<T>`
    Returns:
      `true` if completed with an error or cancellation

  - ### then

    public <U> Awaitable<U> then(Function<? super T,? extends U> fn)
    Returns a new `Awaitable` whose result is obtained by applying the given function to this awaitable's result when it completes.

    Returns a new `GroovyPromise` whose result is obtained by applying the given function to this promise's result. The current `AsyncContext` snapshot is captured when the continuation is registered and restored when it executes.

    Specified by:
      `then` in interface `Awaitable<T>`
    Type Parameters:
      `U` - the type of the mapped result
    Parameters:
      `fn` - the mapping function
    Returns:
      a new awaitable holding the mapped result

  - ### thenCompose

    public <U> Awaitable<U> thenCompose(Function<? super T,? extends Awaitable<U>> fn)
    Returns a new `Awaitable` produced by applying the given async function to this awaitable's result, flattening the nested `Awaitable`. This is the monadic `flatMap` operation for awaitables.

    Returns a new `GroovyPromise` that is the result of composing this promise with the async function, enabling flat-mapping of awaitables. The current `AsyncContext` snapshot is captured when the continuation is registered and restored when it executes.

    Specified by:
      `thenCompose` in interface `Awaitable<T>`
    Type Parameters:
      `U` - the type of the inner awaitable's result
    Parameters:
      `fn` - the async mapping function that returns an `Awaitable`
    Returns:
      a new awaitable holding the inner result

  - ### exceptionally

    public Awaitable<T> exceptionally(Function<Throwable,? extends T> fn)
    Returns a new `Awaitable` that, if this one completes exceptionally, applies the given function to the exception to produce a recovery value. The throwable passed to the function is deeply unwrapped to strip JDK wrapper layers.

    Returns a new `GroovyPromise` that handles exceptions thrown by this promise. The throwable passed to the handler is deeply unwrapped to strip JDK wrapper layers (`CompletionException`, `ExecutionException`). The handler runs with the `AsyncContext` snapshot that was active when the recovery continuation was registered.

    Specified by:
      `exceptionally` in interface `Awaitable<T>`
    Parameters:
      `fn` - the recovery function
    Returns:
      a new awaitable that recovers from failures

  - ### toCompletableFuture

    public CompletableFuture<T> toCompletableFuture()
    Converts this `Awaitable` to a JDK `CompletableFuture` for interoperability with APIs that require it.

    Returns the underlying `CompletableFuture` for interop with JDK APIs.

    Specified by:
      `toCompletableFuture` in interface `Awaitable<T>`
    Returns:
      a `CompletableFuture` representing this computation

  - ### toString

    public String toString()
    Returns a human-readable representation showing the promise state: `GroovyPromise{pending}`, `GroovyPromise{completed}`, or `GroovyPromise{failed}`.
    Overrides:
      `toString` in class `Object`