Effect
in package
Command-handler return type for event-sourced actors.
An Effect encodes what the persistence engine should do in response to a
command: persist one or more events, reply to a caller, stash the message for
later processing, stop the actor, or do nothing. The engine executes the effect
after the command handler returns, guaranteeing that side-effects registered via
thenRun() or thenReply() on the persist path only execute once the events
are durably stored.
Side-effect hooks run on EVERY effect, after its primary action. On
Effect::persist(...) they observe the post-persist state; on any other
effect — including Effect::none() — they observe the unchanged current
state. They run at most once, when the command is handled: recovery replay
folds events onto state only and never re-executes them.
Example:
// Persist an event and then reply with the updated state
return Effect::persist(new ItemAdded($item))
->thenReply($ctx->sender(), fn(CartState $state) => new CartUpdated($state->items));
// Read-only query: reply with the current state without persisting
return Effect::none()
->thenReply($replyTo, fn(CartState $state) => new CartSnapshot($state));
// Stop the actor
return Effect::stop();
Tags
Table of Contents
Properties
- $events : array<string|int, mixed>
- $replyMsg : mixed
- $replyTo : ActorRef|null
- $sideEffects : array<string|int, mixed>
- $type : EffectType
Methods
- none() : self
- Acknowledge the command without persisting any events.
- persist() : self
- Persist one or more domain events and apply them to the actor state.
- reply() : self
- Send a reply message directly to `$to` as the sole effect of handling a command.
- stash() : self
- Defer the current command by placing it back into the stash buffer.
- stop() : self
- Stop the actor after the current effect (and any side-effects) complete.
- thenReply() : self
- Attach a reply side-effect that runs after the effect's primary action.
- thenRun() : self
- Attach an arbitrary side-effect closure that runs after the effect's primary action.
- unhandled() : self
- Signal that the command was not handled by the current behavior.
Properties
$events
public
array<string|int, mixed>
$events
= []
$replyMsg
public
mixed
$replyMsg
= null
$replyTo
public
ActorRef|null
$replyTo
= null
$sideEffects
public
array<string|int, mixed>
$sideEffects
= []
$type
public
EffectType
$type
Methods
none()
Acknowledge the command without persisting any events.
public
static none() : self
Use this for read-only commands or when a command is intentionally a no-op.
Side-effect hooks chained on none() execute with the unchanged current
state — Effect::none()->thenReply(...) is the canonical read-only query.
Return values
selfpersist()
Persist one or more domain events and apply them to the actor state.
public
static persist(object ...$events) : self
Events are written to the EventStore before any side-effects run.
Chain thenRun() or thenReply() to execute callbacks after they are stored.
Parameters
- $events : object
Return values
selfreply()
Send a reply message directly to `$to` as the sole effect of handling a command.
public
static reply(ActorRef $to, object $message) : self
Use this when no state change is needed; for read commands that need a reply
after persisting events, prefer Effect::persist(...)->thenReply(...) instead.
Parameters
- $to : ActorRef
-
The actor to reply to (typically the command sender).
- $message : object
-
The reply message to send.
Return values
selfstash()
Defer the current command by placing it back into the stash buffer.
public
static stash() : self
The stashed command is replayed automatically once the actor calls
$ctx->unstashAll(). Useful during recovery or state-machine transitions.
Return values
selfstop()
Stop the actor after the current effect (and any side-effects) complete.
public
static stop() : self
Return values
selfthenReply()
Attach a reply side-effect that runs after the effect's primary action.
public
thenReply(ActorRef $to, callable(TState): TReply $fn) : self
The closure receives the state and must return the reply object to send
to $to. On Effect::persist(...) it runs after the events are durably
stored and receives the post-persist state; on any other effect it
receives the unchanged current state. Multiple thenReply() calls chain
additional replies.
Parameters
- $to : ActorRef
- $fn : callable(TState): TReply
-
receives final state, returns reply message
Tags
Return values
selfthenRun()
Attach an arbitrary side-effect closure that runs after the effect's primary action.
public
thenRun(callable(TState): void $fn) : self
The closure receives the state for inspection: the post-persist state on
Effect::persist(...) (after the write completes), the unchanged current
state on any other effect. Multiple thenRun() calls chain additional
side-effects; they execute in registration order. Hooks run at most once,
when the command is handled — never during recovery replay.
Parameters
- $fn : callable(TState): void
-
receives final state
Tags
Return values
selfunhandled()
Signal that the command was not handled by the current behavior.
public
static unhandled() : self
The message is routed to dead letters, matching the semantics of
Behavior::unhandled() in the stateless actor model.