Side-effect
trait SideEffect[F[_], S, Alg[_[_]]] {
def apply(trigger: SideEffect.Trigger, effector: Effector[F, S, Alg]): F[Unit]
def runModeFor(trigger: SideEffect.Trigger, state: Option[S]): F[SideEffect.RunMode]
}
SideEffect
is parametrized with the following type parameters:
F[_]
: abstract effectful contextF
encapsulating all values, e.g.IO[*]
Alg[_[_]]
: entity algebra, allowing “back-interaction” with the entity itself (e.g. for at least once process definition, see note in Effector)S
: entity state, e.g. Booking
It represents a side-effect that is triggered according to trigger
either after event persistence, command handling (for a read-only behavior invocation) or recovery. Side-effects are typically asynchronous operations such as kafka writes, outgoing REST requests, and entity passivation (flushing out of memory).
In the runtime, the resulting F[Unit]
is interpreted according to the RunMode
setting indicated by a preliminary call to runModeFor
. With Async
mode, it triggers in run & forget mode so that command reply is not delayed by any lengthy side-effect. With Async
mode, it triggers in run & forget mode so that any lengthy side-effect does not delay command reply. With Sync
mode, the side-effect runs to completion before the entity processes the next command: this can simplify the side-effect logic as it precludes accounting for concurrency, but can hurt the system’s responsiveness. The default implementation of runModeFor
sets it to Async
.
The passed Effector instance can be used to access entity state, chain further interactions with the entity itself and to control passivation (for an example, see BookingEffector
Defining a side-effect is entirely optional, pass-in SideEffectInterpreter.unit
in deployRepository
if there are no side-effects to describe.