0

我有一个带有持久演员A的演员系统。在接收到消息M时,这应该生成一个持久性参与者B的实例,该实例执行一些危险且长时间运行的过程(涉及与其他方交换其他消息),并将消息N发送回A。收到N后,A应该终止B

Spawining 是这样实现的:当A接收到M时,它会验证、计算并创建一个事件M',该事件会被持久化。应用事件时,A使用预先计算的信息生成子节点。如果此时系统重新启动,则M'将重播给A,并且它将创建同一个子B的新化身。

我正在努力解决的是在恢复系统时处理终止子的情况:我希望看到任何在重新启动系统之前终止的B 。

最初我只是从父母那里发送毒丸消息,但由于持久演员不存储任何有关接收此类命令的事件,并且只是仁慈地死去,当系统恢复时,他们故事的最后一章不会重播给他们,他们只是继续闲逛。

我采取了不同的方法并尝试在处理AContext.Stop(child)的恢复消息时调用,但这导致所有这些B在它们恢复之前被终止,导致系统记录问题,例如恢复超时。

所以我想我要么必须让B在被杀死之前恢复,要么首先不重新创建它。

我现在要做的是在代表B状态的对象中引入一个标志,创建一个要发送的自定义消息而不是 PoisonPill,以便B可以持续一个被终止的事件,并且当它接收到的信息时恢复完成,检查该字段并自行终止。但是对于一个简单的要求,即在重启时不复活死去的演员,看起来工作量很大,所以我想知道我是在做完全错误的事情还是试图重新发明热水。

4

1 回答 1

1

虽然调用 from 的持久回调Persist(domainEvent, callback)只会被调用一次,但恢复过程的实际处理程序可能(并且可能会)在参与者的生命周期中为同一事件调用多次。出于这个原因,保持它的行为是幂等的很重要——当你在恢复处理程序调用上创建一个新的孩子时,情况并非如此。

对于像你这样的情况,最好的想法似乎是在恢复期间创建一个关于挂起子进程的注释,但是它们的创建应该推迟到恢复过程完成 - 这可以通过覆盖OnReplaySuccess持久参与者的方法来执行。在这一点上,您应该能够确定哪些子actors应该还活着,哪些子actors在过去已经完成了它们的处理,所以只复活必要的actors应该很容易。

于 2018-02-16T15:55:01.580 回答