scala - 在 Akka Typed persistent actor 中创建子 actor

标签 scala akka akka-persistence akka-typed

让我们假设一个使用 Akka Typed 实现的应用程序有一个持久化角色。作为其操作的一部分,这个持久性 actor 创建了 transient (或非持久性)子 actor,每个子 actor 都有一个唯一的 ID,这些 ID 是持久状态的一部分。持久化 actor 还需要某种方式与其子级进行通信,但我们不想持久化子级的 ActorRef,因为它们实际上并不是状态的一部分。在恢复时,持久性 actor 应该根据恢复的状态重新创建它的 child 。这听起来不像是一个非常不寻常的用例,我正试图弄清楚什么是最简洁的实现方式。我可以在我的命令处理程序中的 andThen Effect 中创建 child Actor ,这是为了副作用,但是没有办法保存 child 的 ActorRef 从那里。这似乎是类型化 Persistence API 的一个更普遍的特征——在持久性 actor 中很难有非持久性状态(在这种情况下可以用于存储 transient 子 ActorRef)。我想出的一个解决方案是使用一种“代理”actor 来创建子级,保留 ID 和 ActorRef 的映射,并根据 ID 转发消息。持久性 actor 持有对该代理 actor 的引用,并在每次需要创建新 child 或向其中一个现有 child 发送内容时联系它。不过,我对此有不同的看法,如果有人能指出我更好的解决方案,我将不胜感激。

最佳答案

如果您不使用快照,那么持久性机制不会存储 State 对象,它会存储导致该 State< 的 Event 序列 对象。在恢复时,它只是按照发生的顺序重新播放那些 Event,您的 eventHandler 将返回一个修改后的 State 对象,该对象反射(reflect)了每个事件的影响。

这意味着 State 对象可以包含本身不持久但仅由某些 Event 的处理设置的值。实际上,它们是从 State 中的持久值派生的缓存值。

在您的情况下,导致创建 transient actor 的操作将被捕获为 actor 上的 Event。因此,您可以在 eventHandler 中创建 transient actor,并将 ActorRef 放入新的 State 对象中。当 actor 恢复时,它将重播该事件,您的 actor 将重新创建 transient actor。

如果您正在使用快照,那么我不认为快照对象与您的 State 对象类型相同,因此您可以在没有 ActorRef 的情况下快照状态 并在收到 SnapshotOffer 消息时重新创建它们。

关于scala - 在 Akka Typed persistent actor 中创建子 actor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51617841/

相关文章:

scala - 读取保存在 HBase 列中的 AVRO 结构

java - 为什么这个用于检索当前年份的 Scala 代码返回 "113"?

java - 案例类对象上的 Scala groupBy

scala - 负载均衡 akka-http

scala - 何时设计可扩展性?

java - akka.persistence.typed.internal.JournalFailureException : Exception during recovery. 如何解决?

scala - 如何在 Scala Slick 中运行补丁/部分数据库更新?

java - 非并发环境下Akka框架的使用

domain-driven-design - 领域事件与事件溯源和 CQRS 的因果关系

scala - 为什么在http服务器和数据库之间使用Actors