I am trying to set up an EventSourcedBehavior whose State is a combination of data retrieved from a DB and events consumed from Kafka. How/where can I inject the former? I can imagine two options:
-
When the behavior is initialized, send a Load Command to it from the outside. I don’t see how this is possible a) because I have no reference to the “actorRef” anywhere that I can see (following the ShoppingCart approach) and b) the Behavior is initialized in response to the first Kafka message, so presumably that message is going to be first in the mailbox
-
In the CommandHandler, check for whether we are fully initialized, and if not, stash the current command, initialize the data from the DB, and then unstash. I am trying to implement this approach, but the limited Effect options don’t seem to support that. What I have is
private def handleCommand(
context: ActorContext[Command],
state: State,
command: Command
)(implicit ec: ExecutionContext): Effect[Event, State] = {
if (state.isInitialized) {
initializedCommandHandler(context, sessionId, state, command)
} else {
uninitializedCommandHandler(state)
}
}
private def initializedCommandHandler(
context: ActorContext[Command],
sessionId: String,
state: State,
command: Command
): Effect[Event, State] = {
command match {
case Update(_) =>
case ShutDown(_) =>
}
}
private def uninitializedCommandHandler(
state: State
)(implicit ec: ExecutionContext): Effect[Event, State] = {
Effect.stash()
val targets = loadFromDb(state)
Effect.persist(Initialized(targets)).thenUnstashAll()
}
I was looking for some way to do something like this.
Effect.stash
.thenRun(loadFromDb()) // does not compile - no such option, contrary to docs on stash method
.andThen(data => Effect.persist(Initialized(data)).thenUnstashAll()
What would be the correct way to do this?
Thanks!