我必须创建一组持久性参与者,并通过一些ID将消息路由给他们。 当我这样做时,我会在路由器演员中使用类似以下的命令查找目标对象:
context.child(id) getOrElse create(id) - creating actors by context.actorOf()
,并且路由器找到子节点之后,它将转发消息(否则首先创建子节点)。
为了节省空间,我还通过调用子actor来对子actor使用某种自定义钝化-setReceiveTimeout
=> ReceiveTimeout
=>发送要钝化的actor自定义Shutdown消息,它在收到context.stop(self)
后会被调用。
如果实际的actor关闭发生在父actor已将ActorRef
发送给已经停止的孩子之后但在转发消息之前发生了呢?消息会丢失吗?
我认为此问题可以通过保存传入的消息并在actor重新激活时重放它们来通过akka分片(可能是ShardRegion)来解决。
问题是由于要求我无法使用Akka分片。 对于钝化参与者的消息处理,是否有现成的解决方案或模式?
谢谢
答案 0 :(得分:0)
路由器和子actor正在异步运行,因此,当子呼叫context.stop(self)
时,邮箱中仍有待处理的消息。在这种情况下,这些消息将丢失(路由到死信)
为避免消息丢失,孩子不能自行关闭,而需要与路由器协调。例如:
setReceiveTimeout
ReceiveTimeout
后,向路由器发送一条自定义Stopping
消息Stopping
时,停止将消息路由到孩子,并将自定义的Stop
消息(或PoisonPill
)发送给孩子Stop
后,致电context.stop(self)
在第3步中,路由器可能需要维护自己的子代地图,而不是依靠context.child
在第4步中,由于保证了两个参与者之间的消息顺序,因此Stop
消息将始终是来自路由器的最后一条消息,因此可以安全地停止。