我可以为其他参与者保留事件吗?

Can I persist events for other actors?

使用 akka-typed 我正在尝试创建一个 event-sourced 应用程序,其中对一个演员的命令可以对另一个演员产生影响。具体我有以下情况:

当 RootActor 发出 CreateBranch 命令时,验证发生,如果一切都是 o.k。结果必须是:

  1. RootActor 将更新该演员children 的列表
  2. BranchActor 将使用一些内容进行初始化(先前在命令中给出)
  3. RootActor 使用 OperationDone
  4. 回复命令的发布者

现在我唯一能想到的是:RootActor 处理事件并作为副作用向 BranchActor 发出命令,BranchActor 反过来保存初始化事件,回复 RootActor,最后回复原始发行人。

不过,这看起来太复杂了,因为:

  1. 我需要使用 pipe to self 机制,这意味着
    • 我还需要管理允许我回复原始发布者的内部命令
    • 我需要处理该操作可能失败的情况,如果失败,则意味着分支的创建不是原子的,而保存两个事件是原子的,从某种意义上说,要么两者都被保存,要么两者都不保存。
  2. 我需要向另一个演员发出另一个命令,但我不需要这样做,因为主要命令应该处理所有事情
  3. 应该验证新命令,但没有必要,因为在这种情况下它来自系统而不是 "external" 用户。

那么我的问题是:我不能只从 RootActor 中保存两个事件,一个给自己,一个给目标 BranchActor? 另外,作为一个额外的问题:这对 event-sourcing 来说是一个好习惯吗?

那么我的问题是:我不能只从 RootActor 保存两个事件,一个给自己,一个给目标 BranchActor?

没有。听起来不是老生常谈,但你唯一能对演员做的就是向它发送信息。如果你必须做你正在做的事情,你就走在正确的道路上。 (例如 pipeTo 等)

这甚至是事件溯源的好做法吗?

这不是一个好的做法。它是次优的还是彻底的反模式仍然值得商榷。 (我觉得我自信地说这句话是因为 Lightbend Discussion thread 一方争论 "tricky but I have no regrets" 而另一方争论 "explicit anti-pattern"。)

引用内部 Slack 中的某人(我不想在未经他许可的情况下归因于他,但我保存了它,因为它似乎非常优雅地总结了这种情况。)

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.

如果您无法修复聚合,使一个参与者负责整个一致性边界,更好的做法是事先丰富命令:本质上是构建一个 Saga 模式。