Luca
Luca

Reputation: 1166

Can I persist events for other actors?

Using akka-typed I'm trying to create an event-sourced application in which a command on an actor can cause effect on another actor. Specifically I have the following situation:

When RootActor is issued a CreateBranch command, validation happens, and if everything is o.k. the results must be:

  1. RootActor will update the list of children of that actor
  2. BranchActor will be initialized with some contents (previously given in the command)
  3. RootActor replies to the issuer of the command with OperationDone

Right now the only thing I could come up with is: RootActor processes the Event and as a side effect issues a command to the BranchActor, which in turn saves an initialization eventt, replies to the RootActor, which finally replies to the original issuer.

This looks way too complicated, though, because:

  1. I need to use a pipe to self mechanism, which implies that
    • I need to manage internal commands as well that allow me to reply to the original issuer
    • I need to manage the case where that operation might fail, and if this fails, it means that the creation of a branch is not atomic, whereas saving two events is atomic, in the sense that either both are saved or neither is.
  2. I need to issue another command to another actor, but I shouldn't need to do that, because the primary command should take care of everything
  3. The new command should be validated, though it is not necessary because it comes from the system and not an "external" user in this case.

My question then is: can't I just save from the RootActor two events, one for self, and one for a target BranchActor? Also, as a bonus question: is this even a good practice for event-sourcing?

Upvotes: 1

Views: 173

Answers (1)

David Ogren
David Ogren

Reputation: 4810

My question then is: can't I just save from the RootActor two events, one for self, and one for a target BranchActor?

No. Not to sound trite, but the only thing you can do to an actor is to send a message to it. If you must do what you are doing you are doing, you are on the right path. (e.g. pipeTo etc.)

is this even a good practice for event-sourcing?

It's not a good practice. Whether it's suboptimal or a flat out anti-pattern is still debatable. (I feel like I say say this confidently because of this Lightbend Discussion thread where it was debated with one side arguing "tricky but I have no regrets" and the other side arguing "explicit anti-pattern".)

To quote someone from an internal Slack (I don't want attribute him without his permission, but I saved it because it seemed to so elegantly sum up this kind of scenario.)

If an event sourced actor needs to contact another actor to make the decision if it can persist an event, then we are not modeling a consistency boundary anymore. It should only rely on the state that [it has] in scope (own state and incoming command). … all the gymnastics (persist the fact that its awaiting confirmation, stash, pipe to self) to make it work properly is an indication that we are not respecting the consistency boundary.

If you can't fix your aggregates such that one actor is responsible for the entire consistency boundary the better practice is to enrich the command beforehand: essentially building a Saga pattern.

Upvotes: 1

Related Questions