Akka演员中的消息传递顺序

15

我对Akka比较新,无法在参考手册中找到答案。

假设我们有远程Actor分布在由3台机器(A、B、C)组成的集群中,其中一台机器上有一个Actor,其他机器有ActorRef指向另外两台机器上的Actor,即:

Machine A:
A (real actor)
-> B (ref)
-> C (ref)

Machine B:
-> A (ref)
B (real actor)
-> C (ref)

Machine C:
-> A (ref)
-> B (ref)
C (real actor)

演员A执行了以下代码:

bRef ! msg1
bRef ! msg2

Actor B 在消息处理程序中执行以下代码:

case msg1 => 
    cRef ! msg3
    aRef ! msg4

Actor C在消息处理程序中执行以下代码:

case msg3 => 
    aRef ! msg5

我能做出如下的假设(如果有的话):

  1. 演员B在收到msg2之前会先收到msg1

  2. 演员A在收到msg4之前会先收到msg5

接下来的问题可能会帮助理解上述内容: 通过!运算符发送的消息是否真正异步地通过网络发送,还是等待接收邮箱收到它才会发送? 即下面的代码行:

bRef ! msg1

阻塞直到Actor B在其邮箱中收到消息或者它生成了处理传递的线程并继续执行。

bRef ! msg2

即使 Actor B 收到了 msg1,Actor A 还没有意识到这一点,是吗?

2个回答

9
对于(1),您可以保证dispatcher在msg2之前将msg1排队。实际上,它们排队后会发生什么取决于您使用的dispatcher:http://akka.io/docs/akka/1.1.2/scala/dispatchers.html,但在您的情况下,只要B能接受这两个消息,那么它总是会在接收msg2之前接收到msg1。
对于(2),不,您无法保证这一点。!方法在dispatcher将消息排队而不是目标actor的邮箱接受消息时立即返回。发送操作在另一个线程中完成,因此可能会遇到各种竞态条件。

通过!运算符发送的消息是否真正异步地通过网络发送,还是等待接收邮箱收到它?

您可以使用带有本地actor的BoundedMailbox来展示使用!将消息排队到dispatcher是异步的:
class TestActor extends Actor {
  val mailboxCapacity = BoundedMailbox(capacity = 1)
  self.dispatcher = Dispatchers.newExecutorBasedEventDrivenDispatcher("test", 1, mailboxCapacity).build

  def receive = {
    case x: String => 
      Thread.sleep(1000)
      println("Received message")
    case _ => 
  }
}

val t = Actor.actorOf[TestActor]
t.start()

t ! "one"; t ! "two"; t ! "three"; println("Main thread");

输出:

scala>     t ! "one"; t ! "two"; t ! "three"; println("Main thread");
Received message
Main thread

scala> Received message
Received message

这意味着在你知道消息是否被传递之前,主线程中的代码执行就已经继续了。在这种情况下,如果我们在调度器上设置了pushTimeout并使Thread.sleep等待时间超过超时时间,消息发送很容易超时。

与使用!!相比较:

scala>     t !! "one"; t !! "two"; t !! "three"; println("test");
Received message
Received message
Received message
test

因此,要实现(2),需要采取以下措施:
case msg1 =>
  cRef !! msg3
  aRef ! msg4 

你实际上并没有解决 1 和 2,尽管你可以从你所展示的内容推断出 2 并不成立。然而这并没有与 1 相关联。 - Rex Kerr
你说得对。我修改了我的答案以回答我正在回答的具体问题。 - David McLaughlin
你确定要实现(2),我不需要同时改变 actor C 代码中的 aRef!!msg5吗? - Grozz
1
你能解释一下 !! 是什么意思,或者提供一个关于它的 Akka 文档页面的链接吗?显然它像 ? 一样等待,但我在谷歌上或者 Akka 源代码中找不到任何相关信息。 - chbrown
@chbrown 你最终解决了吗!! - Andrew Cassidy

0

Erlang 给你第一个保证,但不是第二个。Akka 可能也会给你第一个保证,但肯定不会给你第二个保证。

我不知道你后续问题的答案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接