在Akka中创建儿童演员

3df52oht  于 2022-11-06  发布在  其他
关注(0)|答案(2)|浏览(163)

让我们假设一个使用Akka Typed实现的应用程序有一个持久化的参与者。(或非持久性)子参与者,每个子参与者都有一个唯一的ID,这些ID是持久性状态的一部分。持久性参与者还需要某种与其子参与者通信的方式,但我们不想持久化子级的ActorRef,因为它们实际上并不是状态的一部分。在恢复时,持久化参与者应该基于恢复的状态重新创建它的子级。这听起来并不像是一个非常不寻常的用例,我想知道什么是最简洁的实现方式,我可以在命令处理程序的andThenEffect中创建子角色,但是这样就没有办法从那里保存子对象的ActorRef了。在持久参与者中很难有非持久状态(在本例中,它可以用于存储临时子对象ActorRef)我提出的一个解决方案是使用一种“代理”角色来创建子对象,保存ID并且在每次需要创建一个新的子节点或向一个现有的子节点发送消息时联系它。我对此百感交集,如果有人能给我指出一个更好的解决方案,我将不胜感激。

qnzebej0

qnzebej01#

如果你没有使用快照,那么持久化机制不会存储State对象,它会存储导致State对象的Event序列。在恢复时,它只会按照它们发生的顺序重放那些Event,而你的eventHandler将返回一个修改过的State对象,反映每个事件的效果。
这意味着State对象可以包含本身不是持久化的值,而只是通过处理某些Event来设置的值。实际上,它们是从State中的持久化值派生的缓存值。
在您的示例中,导致创建临时参与者的操作将被捕获为参与者上的Event。因此,您可以在eventHandler中创建临时参与者,并将ActorRef放在新的State对象中。当恢复参与者时,它将重播该事件,您的参与者将重新创建临时参与者。
如果您使用快照,那么我认为不需要快照对象与State对象的类型相同,因此您可以在没有ActorRef的情况下对状态进行快照,并在收到SnapshotOffer消息时重新创建它们。

wfauudbj

wfauudbj2#

类型化持久性的一个设计目标是,State可以从事件(或者从快照和自该快照以来的事件)中完全恢复。
一般来说,拥有非持久状态的唯一方法是将EventSourcedBehavior封装在一个设置状态的Behaviors.setup块中。一种选择是在setup中放置某种可变状态(例如var或(可能是互斥或)可变集合),由命令/事件/恢复处理程序操作。
一个更不可变的替代方法是在setup中定义一个不可变的fixture,它包含一个在setup中产生的子actor来管理非持久状态。您还可以将实体ID或其他至少对于实体的这个化身不可变的东西放入fixture中。

相关问题