在 Akka 的 persistent actor 中,创建一个 child actor 被认为是副作用,还是状态的创建?

In Akka's persistent actor, is creating a child actor considered to be a side effect, or the creation of state?

这个问题并不像标题所暗示的那样哲学。考虑以下持久性方法:

执行操作的命令来自各种客户端。我将运营和客户都表示为持久的参与者。 Client 的状态是最后一个通过的 lastOperationId。 Operation 的状态几乎是 Operation 进度的 FSM(它实际上是一个 Saga,因为它需要接触到 ActorSystem 外部的其他系统才能通过它的状态)。

一个Reception actor接收操作命令,其中包含client id和operation id。 Reception actor 创建或检索 Client actor 并将命令转发给它。 Client actor 读取并验证操作命令,持久化它,创建一个 OperationReceived 事件,用这个操作 id 更新它自己的状态。现在它需要创建一个新的 Operation actor 来管理新的 long-running 操作。但这是我迷路的地方,文档和各种博客中的所有好示例都无济于事。大多数评论员说 PersistentActor 将命令转换为事件,然后更新它们的状态。只要在重放期间不调用它们,它们也可能有副作用。所以我有两个困惑的地方:

  1. 在此上下文中创建操作参与者是否等同于 创建状态,还是执行副作用?它看起来不像是副作用,但同时它并没有改变自己的状态,而是在新的 child.
  2. 中引起状态变化
  3. 我应该构建一个命令发送给新的操作演员还是我会 简单地转发它的 OperationReceived 事件?

如果我假设创建 child actor 不是副作用,这意味着我还必须在重播时创建 child。这反过来会导致 child 的状态恢复。

我希望基本问题是清楚的。我觉得这是一个普遍的问题,但我能提出的最好方法是举一个具体的例子。

编辑: 回想起来,我认为从另一个持久化 actor 中创建一个持久化 actor 是一种创建状态的行为,尽管是外包的。这意味着触发创建的事件将在随后的重播中触发该创建(这将导致检索 child 自己的持久状态)。这让我认为传递事件(而不是包装命令)可能是最干净的事情,因为可以应用相同的事件来更新 parent 和 child 中的状态。当事件进入 child 时,应该没有必要保留该事件 - 它已经在 parent 中保留并将重播。

经过反思,我认为从另一个持久化 actor 创建一个持久化 actor 是一种创建状态的行为,尽管是外包的。这意味着触发创建的事件将在随后的重播中触发相同的创建。这让我认为传递事件(而不是包装命令)可能是最干净的事情,因为可以应用相同的事件来更新父项和子项的状态。应该没有必要在事件进入子级时持久化 - 它已经在父级中持久化并将重播。