微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Akka Typed Cluster Sharding 中,保留 EntityRef 以备将来使用是否安全?

如何解决在 Akka Typed Cluster Sharding 中,保留 EntityRef 以备将来使用是否安全?

我目前正在考虑让两个不同的持久 actor 相互通信。特别是:

Given an Actor A exists
When an Actor B is spawned
Then Actor B must have a reference to Actor A
And Actor B must be able to continuously send messages to Actor A even after relocation

我知道有两种选择:

// With an EntityRef
val counterOne: EntityRef[Counter.Command] = sharding.entityRefFor(TypeKey,"counter-1")
counterOne ! Counter.Increment

// Entity id is specified via an `ShardingEnvelope`
shardRegion ! ShardingEnvelope("counter-1",Counter.Increment)

第二个选项似乎是一个不错的方法,因为我会将实体的实际引用的解析委托给 Akka。我可能只需要在实例化时将一些包装函数传递给我的 Actor。例如

val shardRegionA: ActorRef[ShardingEnvelope[Counter.Command]] =
  sharding.init(Entity(TypeA)(createBehavior = entityContext => A()))

def delegate_A(id,message) = {
    shardRegionA ! ShardingEnvelope(id,message)
}

val shardRegionB: ActorRef[ShardingEnvelope[Counter.Command]] =
  sharding.init(Entity(TypeB)(createBehavior = entityContext => B(delegate_A)))

--------

object B {
    def apply(delegate) = {
        ...somewhere inside the state...
        delegate("some_id_of_A",Message("Hello"))
        ...somewhere inside the state...
    }
}

但是,我还想了解第一个选项是否更简单,因为 EntityRef 可能会在状态/事件中安全地持久化。

object B {
    def apply(entityRefA : EntityRef[A]) = {
       EventSourcedBehavior[...](
           emptyState = State(entityRefA)
       )
    }
}

有人对此有任何见解吗?

解决方法

EntityRef 在状态/事件中不能安全地持久化(除非一些非常脆弱的基于反射的序列化),因为它不会公开允许反序列化器重建等效 EntityRef 的信息.默认的 Jackson 序列化也不能有效地反序列化 EntityRef

截至本答案发布时,有一个 PR 允许提取 EntityRef 的“定义”组件以进行序列化(例如,EntityRef[Employee.Command] 可以被 JSON 序列化为{ "entityId": "123456789","typeKey": "EMPLOYEE" }。该 PR 仍然需要对包含 EntityRef 的任何消息、持久事件或状态(如果是快照)进行自定义序列化,但至少可以包含 EntityRef s 在这样的对象中。

在那之前,您不应将 EntityRef 放入消息、事件或可快照状态:相反,您基本上必须将 ID 放入这些对象中,并将包裹在 ShardingEnvelope 中的消息发送到分片区域actor(这就是EntityRef.tell 所做的)。在某些情况下,在非持久性子角色中维护实体 ID 到 EntityRef 的映射并通过该子角色向 EntityRef 发送消息可能是合理的,或者如果愿意阻止或真的会扭曲你的协议,请让那个孩子为你解决EntityRef问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?