Class DefaultActor<T>
- Type Parameters:
T- the message type
- All Implemented Interfaces:
Actor<T>,AutoCloseable
Actor.
Each actor runs on a dedicated worker thread (virtual on JDK 21+) and
dispatches messages sequentially from a FIFO mailbox, guaranteeing
thread-safe state access without locks. The mailbox is a
LinkedBlockingDeque so that
ActorContext.unstashAll() can re-inject deferred messages at
the head of the queue; a Semaphore gates send-side capacity
for bounded mailboxes (the deque itself is internally unbounded). A
message's permit is released as soon as the worker takes it from the
deque — so the bound applies to the queue, not to messages currently
being processed or held in the stash buffer; the stash buffer itself
is unbounded.
- Since:
- 6.0.0
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionstatic Actor<?>Implementation hook forActor.currentSelf().booleanisActive()Returnstruewhile the actor is accepting new sends.booleanReturnstrueonce the worker has fully exited — i.e.onError(TriConsumer<ActorContext<T>, Throwable, ? super T> handler) Context-aware variant ofActor.onError(BiConsumer).onError(BiConsumer<Throwable, ? super T> handler) Registers a handler invoked when the message processor throws.static <T,R> Actor<T> reactor(ReactorHandler<T, R> handler, ActorOptions options) Context-aware variant ofActor.reactor(Function, ActorOptions).static <T,R> Actor<T> reactor(Function<T, R> handler, ActorOptions options) Creates a stateless reactor actor with explicitActorOptionscontrolling the mailbox and executor.voidSends a message to this actor.<R> Awaitable<R>sendAndGet(T message) Sends a message and returns anAwaitablethat completes with the reply.static <T,S> Actor<T> stateful(S initialState, StatefulHandler<S, T> handler, ActorOptions options) Context-aware variant ofActor.stateful(Object, BiFunction, ActorOptions).static <T,S> Actor<T> stateful(S initialState, BiFunction<S, T, S> handler, ActorOptions options) Creates a stateful actor with explicitActorOptionscontrolling the mailbox and executor.voidstop()Stops this actor gracefully.toString()
-
Method Details
-
currentlyExecuting
Implementation hook forActor.currentSelf(). -
reactor
Description copied from interface:ActorCreates a stateless reactor actor with explicitActorOptionscontrolling the mailbox and executor. -
reactor
Description copied from interface:ActorContext-aware variant ofActor.reactor(Function, ActorOptions). -
stateful
public static <T,S> Actor<T> stateful(S initialState, BiFunction<S, T, S> handler, ActorOptions options) Description copied from interface:ActorCreates a stateful actor with explicitActorOptionscontrolling the mailbox and executor. -
stateful
public static <T,S> Actor<T> stateful(S initialState, StatefulHandler<S, T> handler, ActorOptions options) Description copied from interface:ActorContext-aware variant ofActor.stateful(Object, BiFunction, ActorOptions). -
send
Description copied from interface:ActorSends a message to this actor. The message is queued and processed asynchronously. Fire-and-forget — no reply is expected.Bounded-mailbox interaction (see
ActorOptions.Overflow):BLOCK: the calling thread blocks until queue capacity is available, then enqueues.FAIL: throwsIllegalStateExceptionwhen the mailbox is full.DROP_NEWEST: the message is silently dropped — there is no reply to carry the failure, so a fire-and-forget overflow is invisible to the sender. If you need drop visibility, preferActor.sendAndGet(T)(which binds the dropped reply toIllegalStateException) or a different overflow policy.
-
sendAndGet
Description copied from interface:ActorSends a message and returns anAwaitablethat completes with the reply. For reactors, the reply is the handler's return value. For stateful actors, the reply is the new state.Bounded-mailbox interaction (see
ActorOptions.Overflow):BLOCK: the calling thread blocks until queue capacity is available, then enqueues.FAIL: throwsIllegalStateExceptionwhen the mailbox is full.DROP_NEWEST: returns anAwaitablethat completes exceptionally withIllegalStateExceptionindicating the message was dropped; the handler is never invoked.
- Specified by:
sendAndGetin interfaceActor<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:ActorReturnstruewhile the actor is accepting new sends.The actor lifecycle has three states, expressed via this method and
Actor.isTerminated():- accepting —
isActive() == true,isTerminated() == false: the actor accepts new sends and is processing them. - draining —
isActive() == false,isTerminated() == false: entered immediately whenActor.stop()is called. Further sends throwIllegalStateException, but messages already queued (or sent in a race withstop) continue to run. - terminated —
isActive() == false,isTerminated() == true: the worker has exited; the queue and any stash have been processed (or, for stashedsendAndGetreplies, rejected).
- accepting —
-
isTerminated
public boolean isTerminated()Description copied from interface:ActorReturnstrueonce the worker has fully exited — i.e. the queue and any stashed messages have been processed (or rejected, in the case of stashedsendAndGetreplies). AlwaysfalsewhileActor.isActive()is true; becomes true some time afterActor.stop()is called, once draining completes.- Specified by:
isTerminatedin interfaceActor<T>
-
stop
public void stop()Description copied from interface:ActorStops this actor gracefully. Messages already in the queue are processed before the actor shuts down. New sends after stop throwIllegalStateException. -
onError
Description copied from interface:ActorRegisters a handler invoked when the message processor throws.Fire-and-forget
Actor.send(T)otherwise has no way to surface a handler exception; this hook is the supported way to log, record metrics for, or react to those failures. ForActor.sendAndGet(T)the failure is still reported through the returnedAwaitable; theonErrorhandler runs in addition.To stop the actor from inside an error handler, prefer the context-aware overload
Actor.onError(TriConsumer)—ctx.self().stop()works on any actor. Alternatively, if the actor was built withwithCurrentSelf(true), callActor.; without that opt-incurrentSelf().stop() currentSelf()throws.Exceptions thrown from the handler itself are caught and discarded so the actor's processing loop is not destabilised. Replacing a previously registered handler replaces it wholesale — there is no chaining.
Register before the first send. An
onErrorcall that happens after a message is already in flight may not see that message's failure: only handlers visible to the worker by the time it dispatches a given message are invoked for it. To guarantee coverage, chainonErrorinto actor construction — as in the example below — and avoid registering it later.def actor = Actor.reactor(handler).onError { Throwable t, msg -> log.warn("actor failed processing {}", msg, t) } -
onError
Description copied from interface:ActorContext-aware variant ofActor.onError(BiConsumer). The handler receives anActorContextthat can be used to stop the actor viactx.self().stop(). -
toString
-