首页 > 解决方案 > 什么时候可以通过初始创建一个actor来重新排序初始消息?

问题描述

在 Akka 中,消息排序仅在“给定的一对参与者”(source)之间得到保证。

同一页面还声明“此规则不可传递”,并给出了 Actor 向 ActorA发送消息的理论示例,然后将消息发送给M1Actor ,Actor 将消息转发给 Actor 。因此,actor可以按任何顺序接收。CM2BCCM1M2

该页面还强调了创建参与者与向其发送消息的方式相同,因此,任何其他外部参与者最终如何向尚不存在的参与者发送消息:

Actor 创建被视为从父级发送给子级的消息,其语义与上面讨论的相同。以可以使用此初始创建消息重新排序的方式向参与者发送消息意味着消息可能不会到达,因为参与者还不存在。[...] 定义良好的排序的一个例子是父级创建一个actor并立即向它发送消息。

到目前为止,一切都很好。问题是,据我所知(我是 Akka 的新手!),Akka 代码中最常用的模式是让一个 actor 产生子代,然后它们的共享父代启动子代之间的通信,因此,这是不是“定义明确的排序”。世界上大多数基于 Akka 构建的应用程序是否从根本上被破坏,等待发生的事故?

以下是 Akka 自己的一些示例。

这个页面上,他们有一个HelloWorldMain产生两个孩子HelloWorldHelloWorldBot. helloWorld.tell()然后,主要调用HelloWorldBotset 作为回复参考。

同一页在课堂上更清楚地重复了这种模式Main

ActorRef<ChatRoom.RoomCommand> chatRoom = context.spawn(ChatRoom.create(), "chatRoom");
ActorRef<ChatRoom.SessionEvent> gabbler = context.spawn(Gabbler.create(), "gabbler");
context.watch(gabbler);
chatRoom.tell(new ChatRoom.GetSession("ol’ Gabbler", gabbler));

引用的第一页给出了一个可能出错的例子;如果“远程部署的actor R1,将其引用发送到另一个远程actor R2 并让R2 向R1 发送消息”。这是一个明显的例子。但是由于我有点不喜欢编写可能无法按预期工作的应用程序,所以我需要了解哪些情况?远程处理只是其中之一——或者,我怀疑,可能是唯一的一个?而且,我可以使用什么模式来使最初的沟通按计划进行?例如,我是否应该在显示它对下一个孩子的引用之前等待一个 actor-start 事件(如果 Akka 中甚至存在这样的“信号”)?

我知道不能保证会传递任何消息-因此,甚至不能保证生成孩子实际上会启动该孩子哈哈。但是,这是一个单独的主题。我特别关心的是孩子的创造,以及 Akka 明确强调的他们之间的初始交流应该遵循“明确”的顺序,然而,实际上似乎没有人真正这样做

标签: akkaactor

解决方案


“与创建相比,初始消息何时会重新排序?”

简短的回答:从不。如果您创建一个ActorRef立即生效的参与者,可以立即接收消息,并且在处理消息之前将处于有效状态。

更长的答案:如果您不直接生成演员,则可能会发生重新排序。因为,正如您所注意到的,订购保证仅适用于一个给定的演员到另一个演员。因此,如果您引入中介,则该保证不再适用。可能发生这种情况的一种情况是使用远程参与者创建,这就是文档中提到它的原因。但是远程actor创建并不是一个典型的场景。

META:我现在完全重写这个答案,以便更简洁,因为我认为我更好地理解了这个问题。(如果您想查看原始漫无边际的答案,请随意使用版本控制功能。)


推荐阅读