Akka 何时可以在初始创建参与者时对初始消息重新排序?

Akka 何时可以在初始创建参与者时对初始消息重新排序?,akka,actor,Akka,Actor,在Akka中,消息顺序只保证在“给定的一对参与者”()之间 同一页还声明“此规则不可传递”,并给出了一个理论示例,即参与者a向参与者C发送消息M1,然后将消息M2发送给参与者B,后者将消息转发给参与者C。因此,参与者C可以按任意顺序接收M1和M2 该页面还强调创建参与者与向其发送消息是如何相同的,因此,任何其他外国参与者如何最终向尚不存在的参与者发送消息: 参与者创建被视为从父级发送到 child,其语义与上面讨论的相同。发送消息 以一种可以使用此首字母重新排序的方式发送给参与者 创建消息意味着

在Akka中,消息顺序只保证在“给定的一对参与者”()之间

同一页还声明“此规则不可传递”,并给出了一个理论示例,即参与者
a
向参与者
C
发送消息
M1
,然后将消息
M2
发送给参与者
B
,后者将消息转发给参与者
C
。因此,参与者
C
可以按任意顺序接收
M1
M2

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

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

到目前为止还不错。问题是,从我所能收集到的(我对Akka是新手!)来看,Akka代码中最常用的模式是让一个参与者产生子代,然后他们的共享父代启动子代之间的通信,因此,这是而不是“定义良好的顺序”。世界上大多数基于Akka的应用程序是否已经根本崩溃,一场事故即将发生

这里有几个来自阿克卡的例子

他们有一个
HelloWorldMain
,它产生了两个子
HelloWorld
HelloWorldBot
。然后,main调用
helloWorld.tell()
,并将
HelloWorldBot
设置为回复引用

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));
ActorRef chatRoom=context.spawn(chatRoom.create(),“chatRoom”);
ActorRef gabbler=context.spawn(gabbler.create(),“gabbler”);
观察(饶舌者);
聊天室.tell(新聊天室.GetSession(“ol'Gabbler”,Gabbler));
引用的第一页给出了一个可能出错的例子;如果“远程部署的参与者R1,将其引用发送给另一个远程参与者R2,并让R2向R1发送消息”。这是显而易见的情况。但由于我不喜欢编写可能无法按预期工作的应用程序,我需要了解的具体案例是什么?远程处理只是其中之一——或者,我怀疑,可能是唯一的一个?我可以用什么样的模式使最初的沟通按计划进行?例如,我是否应该等待演员启动事件,然后再将其引用给下一个孩子(如果Akka中甚至有这样的“信号”)

我明白,没有任何信息是可以保证传递的——因此,即使是产生一个孩子也不能保证真正开始这个孩子的lol。但是,这是一个单独的主题。我特别关注的是儿童的创造,Akka明确强调,他们之间的初始沟通应该遵循“明确定义”的顺序,然而,在实践中似乎没有人真正做到“与创造相比,初始信息何时会被重新排序?”

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

更详细的回答:如果你不直接产生演员,就可能发生重新排序。因为,正如您所注意到的,排序保证只适用于从一个给定的参与者到另一个参与者。因此,如果您引入中介机构,担保将不再适用。可能发生这种情况的一个场景是使用 远程参与者创建,这就是文档中提到它的原因。但远程参与者创建并不是一个典型的场景


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

子参与者始终是local您从哪里了解到参与者位置在消息传递保证的排序语义中起作用?从我目前所读到的,阿克卡只保证“给定的一对演员”之间的秩序。关于这个地方一句话也没有?这会让我吃惊的。因为这也意味着从同一来源发送给不同参与者的消息永远不会被并行处理。这可能会成为一个瓶颈!大卫是对的,如果你直接产生演员,这就不会发生。使用Akka类型的远程部署不再被允许,因此消除了创建和消息发送可能被重新排序的场景。这意味着文档中创建子对象并将actor ref交给其他参与者的所有用法都是安全的,不需要在创建过程中使用额外的模式。一般来说,如果使用经典API,我建议避免使用远程部署。