persistence - 在Akka的持久化actor中,创建子actor被认为是副作用,还是状态的创建?

标签 persistence akka actor

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

执行操作的命令来自各种客户端。我将操作和客户端都表示为持久参与者。客户端的状态是要传递的 lastOperationId。 Operation 的状态几乎是 Operation 进度的 FSM(它实际上是一个 Saga,因为它随后需要与 ActorSystem 外部的其他系统联系,以便在其状态间移动)。

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

  • 在此上下文中创建操作参与者是否等同于
    创建状态,或执行副作用?这似乎不是副作用,但同时它并没有改变自己的状态,而是导致新 child 的状态发生变化。
  • 我应该构造一个命令发送给新的操作 Actor 还是我会
    简单地将它转发到 OperationReceived 事件?

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

    我希望潜在的问题是清楚的。我觉得这是一个笼统的问题,但我能表述它的最好方法是给出一个具体的例子。

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

    最佳答案

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

    关于persistence - 在Akka的持久化actor中,创建子actor被认为是副作用,还是状态的创建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27952041/

    相关文章:

    akka - 带有 Akka.NET : how to prevent sending messages to dead actors 的 Actor 模型

    scala - Akka Actor - 创建 Actor 池

    java - 重新保存修改后的对象时,JPA 合并()无法按预期工作

    java - 使用 Java 和 sbt 依赖项进行 Akka 编程

    scala - Akka Streams 中的 RestartFlow 未按预期工作

    synchronization - Akka:两个 Actor 之间同步状态的正确模式

    java - 用 int 映射枚举的最佳方法

    java - 数据库和文件持久化之间的接口(interface)

    Java JPA GenerationType.Auto 值始终为 null

    java - 在 Actor 中停止 Akka Actor