2011-06-01 73 views
13

我对阿卡很新,在参考手册中找不到答案。akka演员的留言传递顺序

假设我们有分布式3个机(A,B,C),其中一个演员住每台机器上和其他的集群中的远程参与者有actorRef至2个其他的,即:

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) 

演员甲执行以下代码:

bRef ! msg1 
bRef ! msg2 

演员乙执行消息处理程序下面的代码:

case msg1 => 
    cRef ! msg3 
    aRef ! msg4 

演员Ç执行下面的消息处理程序代码:

case msg3 => 
    aRef ! msg5 

我可以做如下假设(如果有的话):

  1. 演员B获得MSG1它得到MSG2

  2. 演员A之前在msg4之前获得msg5

而后续问题是probab ly导致了解上述: 是由!运营商真正异步通过网络还是等到接收邮箱得到它? 也就是说确实行

bRef ! msg1 

块,直至演员的B的邮箱获取消息还是它酿出它处理交货线程和继续执行

bRef ! msg2 

它甚至知道演员B获得了MSG1过吗?

回答

7

对于(1)您保证msg1将在msg2之前由调度程序进入队列。究竟发生什么事情真的取决于你使用哪个调度程序:http://akka.io/docs/akka/1.1.2/scala/dispatchers.html,但在你的情况下,只要B可以接受这两个消息,那么它总是会在msg2之前接收msg1。

对于(2),不,你没有这个保证。 !!方法在调度程序排队消息后立即返回,而不是消息被目标参与者的邮箱接受。发送然后在另一个线程中完成,并受到各种竞争条件的影响。

是由!运营商真正异步通过网络还是等到接收邮箱得到它?

您可以使用BoundedMailbox和本地actor来显示将消息与调度程序排队时与!:

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 
+0

你还没有真正解决过1.和2.,尽管你可以推断出2.不符合你所显示的。然而,这并没有解决1,即使是切向。 – 2011-06-01 14:44:27

+0

你说得对。我修改了我的答案以回答我正在回答的具体问题。 – 2011-06-01 14:51:33

+0

你确定要实现(2)我也不必将actor C代码改为aRef! MSG5? – Grozz 2011-06-02 06:53:08

1

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

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