在Akka的执着演员中,创造一个被认为是副作用的儿童演员,还是创造国家?

Bre*_*dan 7 persistence actor akka

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

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

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

  1. 在此上下文中创建操作actor是否等同于创建状态或执行副作用?它似乎不是副作用,但同时它不会改变自己的状态,而是导致新孩子的状态改变.
  2. 我是否应该构建一个Command来发送给新的Operation actor,或者我只是将它转发给OperationReceived事件?

如果我假设创建一个儿童演员不是副作用,那就意味着我还必须在重播时创建一个孩子.这反过来会导致孩子的状态得以恢复.

我希望潜在的问题是明确的.我觉得这是一个普遍的问题,但我能够制定它的最好方法是给出一个具体的例子.

编辑:经过反思,我认为从另一个创建一个持久的演员是一种创造国家的行为,虽然是外包的.这意味着触发创建的事件将在后续重放时触发该创建(这将导致检索子项自己的持久状态).这使我认为传递事件(而不是包装命令)可能是最干净的事情,因为可以应用相同的事件来更新父和子中的状态.当事件进入孩子时,应该没有必要坚持这个事件 - 它已经存在于父母身上并将重播.

Bre*_*dan 2

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