如何解决Akka actor 化身对于远程调用是否重要?
在 this page,我读到(强调我的):
你可以创建一个actor,终止它,然后创建一个新的actor 具有相同的演员路径。新创建的演员是新的化身 演员的。这不是同一个演员。演员参考旧的 化身对新的化身无效。 消息发送到 即使旧演员参考也不会传递给新的化身 尽管它们的路径相同。*
*为了完整起见,发送到“旧”引用的消息将进入死信邮箱/演员/队列/任何东西。
他们进一步说明(强调我的):
当两个 actor 引用具有相同的路径并指向相同的 actor 化身时,它们被比较为相等。
好的,这很清楚。可以说,actor 引用指向对象的特定实例。
但是在进行远程调用时,实例/“化身”似乎根本不重要。再往下说的是同一页(强调我的):
当通过网络发送一个actor引用时,它被表示 通过它的路径。因此,路径必须完全编码所有信息 向底层参与者发送消息所必需的。这是实现的 通过在路径的地址部分编码协议、主机和端口 细绳。当actor系统从远程接收到actor路径时 节点,它检查该路径的地址是否与 这个演员系统,在这种情况下,它将被解析为演员的 本地参考。
在化身上没有一个字 - 或者,各种实例标识符 - 是“必要信息”的一部分。
这有点矛盾,至少,令人困惑。让我用一个例子来详细说明。
假设我有一个引用 a
和一个引用 b
,它们共享相同的路径。 a
是旧的、死的“化身”。 b
是新的替代化身。在本地使用 a
会将所有消息发送到死信队列。凉爽的。但是,如果我将包含 a
的消息作为消息中的回复演员发送给远程演员,并且该远程演员写回一条消息,那么他的消息会自动转到 b
??>
我很难理解这个,或者更确切地说,理解其中的原理。为什么不同。我的意思是,如果这是真的 - 有区别 - 那么我可以编写一些非常有趣的测试代码,在那里我无法与一个被取代/死人a
交流但如果我把死人a
在与其他任何人的电线上,然后他们可以愉快地与他沟通,而不会出现问题,哈哈。显然我必须遗漏一些东西!
解决方法
崩溃并通过监督重新启动的actor不是新的“化身”,而是会回答相同的ActorRef
(s)。尽管它实际上是一个新实例化的对象,但它是相同actor,从一张干净的表开始,以避免处理由于崩溃而导致的任何内部状态损坏。其他演员可以像什么都没发生一样继续与它互动。
一个actor停止,然后父级开始一个新的(可能完全不同的actor,使用不同的协议)但使用相同的名字,因此路径,是一个新的化身,现有的actor引用了之前的“化身”不要指向这个新演员。
监督重启(和恢复)也不会触发死亡观察,而停止演员会。
这对远程和本地 ActorRef
的工作方式相同。
使用类型化集群,获取远程参与者的唯一方法是从接待员或您已经引用的远程参与者那里获取带有 ActorRef
的消息。
通过 Akka Classic API 中的远程处理,您可以使用仅与路径有关的较低级别的 actorSelection
,然后接受您对“化身”一无所知或者是否曾经有过演员当您向其发送消息时在该路径上运行(如果不是,则消息变为死信),或者您解决它并在该时间点获得 ActorRef
的选择,然后将不再指向一个演员,如果演员停下来(并且消息变成死信)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。