scala - 如何处理发送给被钝化的演员的消息
问题描述
我必须创建一组持久性参与者并通过一些 id 将消息路由给他们。当我这样做时,在我的路由器演员中,我使用以下内容查找目标:
context.child(id) getOrElse create(id) - creating actors by context.actorOf()
在路由器找到孩子之后,它会转发消息(否则首先创建孩子)。
为了节省空间,我还通过调用子actor来对它们使用某种自定义钝化 - setReceiveTimeout
=> ReceiveTimeout
=> 在接收到它调用时向要钝化的actor发送自定义关闭消息context.stop(self)
。
如果实际的actor关闭发生在父actor获取ActorRef
到已经在停止中的子actor之后,但在它转发消息之前呢?消息会丢失吗?
我认为这个问题是在 akka 分片(可能是 ShardRegion)中通过保存传入的消息并在 actor 重新激活时重放它们来处理的。
问题是由于我不能使用 Akka Sharding 的要求。是否有现成的解决方案或模式来处理钝化参与者的消息问题?
谢谢
解决方案
路由器和子actor正在异步运行,因此当子调用时context.stop(self)
,邮箱中仍有待处理的消息总是有可能的。在这种情况下,这些消息将丢失(路由到死信)
为避免消息丢失,孩子不能自行关机,需要与路由器协调。例如:
- 孩子:
setReceiveTimeout
- 孩子:在接收时,向路由器
ReceiveTimeout
发送自定义消息Stopping
- 路由器:在接收
Stopping
时,停止将消息路由到孩子并将自定义Stop
消息(或PoisonPill
)发送给孩子 - 孩子:收到
Stop
,打电话context.stop(self)
在第 3 步中,路由器可能需要维护自己的子地图,而不是依赖context.child
并且在第 4 步中,由于两个参与者之间的消息顺序得到保证,因此Stop
消息将始终是来自路由器的最后一个消息,因此可以安全地停止。
推荐阅读
- java - 模拟存储库调用的返回实体返回 null
- c# - Why declare a local function static in C# 8.0
- typescript - 将泛型数组映射到 TypeScript 类的数组
- rust - Rust 中的面向阶段的分配与 arenas
- genetic-algorithm - 我们可以使用遗传算法来选择最佳网络模型和参数吗?
- oracle - 将数字的特殊字符替换为单词 BI 发布者
- java - 没有找到类 DexPathList
- warpscript - 从 Github 导入私有宏到 Warp10
- macos - Git Issue after update to Mac catalina OS : xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)
- sql - Add / update column from a query SELECT? SQL