Package org.apache.groovy.runtime.async

# Class DefaultActor<T>

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

Type Parameters:
  `T` - the message type

All Implemented Interfaces:
  `Actor<T>`, `AutoCloseable`

public final class DefaultActor<T> extends Object implements Actor<T>
Default implementation of `Actor` using a dedicated thread and a `LinkedBlockingQueue` for message processing.

Each actor runs on its own thread (virtual on JDK 21+). Messages are processed one at a time, guaranteeing thread-safe state access without locks.

Since:
  6.0.0
See Also:
  - `Actor`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `isActive()`
  Returns `true` if this actor is running and accepting messages.
  `static <T, R> Actor<T>`
  `reactor(Function<T,R> handler)`
  Creates a stateless reactor actor.
  `void`
  `send(T message)`
  Sends a message to this actor.
  `<R> Awaitable<R>`
  `sendAndGet(T message)`
  Sends a message and returns an `Awaitable` that completes with the reply.
  `static <T, S> Actor<T>`
  `stateful(S initialState, BiFunction<S,T,S> handler)`
  Creates a stateful actor.
  `void`
  `stop()`
  Stops this actor gracefully.
  `String`
  `toString()`

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

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

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

  `close`

- ## Method Details

  - ### reactor

    public static <T, R> Actor<T> reactor(Function<T,R> handler)
    Description copied from interface: `Actor`
    Creates a stateless reactor actor. Each message is passed to the handler function, and the return value becomes the reply for `Actor.sendAndGet(T)` callers.

         var doubler = Actor.reactor(n -> (int) n * 2);
         System.out.println(AsyncSupport.await(doubler.sendAndGet(5))); // 10

    Type Parameters:
      `T` - the message type
      `R` - the reply type
    Parameters:
      `handler` - the message processing function
    Returns:
      a started actor

  - ### stateful

    public static <T, S> Actor<T> stateful(S initialState, BiFunction<S,T,S> handler)
    Description copied from interface: `Actor`
    Creates a stateful actor. The handler receives the current state and the message, and returns the new state. For `Actor.sendAndGet(T)` callers, the new state is the reply.

         var counter = Actor.stateful(0, (state, msg) -> {
             if ("increment".equals(msg)) return (int) state + 1;
             return state;
         });
         counter.send("increment");
         System.out.println(AsyncSupport.await(counter.sendAndGet("increment"))); // 2

    Type Parameters:
      `T` - the message type
      `S` - the state type
    Parameters:
      `initialState` - the initial state
      `handler` - receives (state, message), returns new state
    Returns:
      a started actor

  - ### send

    public void send(T message)
    Description copied from interface: `Actor`
    Sends a message to this actor. The message is queued and processed asynchronously. Fire-and-forget — no reply is expected.
    Specified by:
      `send` in interface `Actor<T>`
    Parameters:
      `message` - the message to send

  - ### sendAndGet

    public <R> Awaitable<R> sendAndGet(T message)
    Description copied from interface: `Actor`
    Sends a message and returns an `Awaitable` that completes with the reply. For reactors, the reply is the handler's return value. For stateful actors, the reply is the new state.
    Specified by:
      `sendAndGet` in interface `Actor<T>`
    Type Parameters:
      `R` - the reply type
    Parameters:
      `message` - the message to send
    Returns:
      an awaitable reply

  - ### isActive

    public boolean isActive()
    Description copied from interface: `Actor`
    Returns `true` if this actor is running and accepting messages.
    Specified by:
      `isActive` in interface `Actor<T>`

  - ### stop

    public void stop()
    Description copied from interface: `Actor`
    Stops this actor gracefully. Messages already in the queue are processed before the actor shuts down. New sends after stop throw `IllegalStateException`.
    Specified by:
      `stop` in interface `Actor<T>`

  - ### toString

    public String toString()
    Overrides:
      `toString` in class `Object`