Gro*_*ozz 15 scala messages mq actor akka
我是Akka的新手,在参考手册中找不到答案.
假设我们有远程actor分布在3台机器(A,B,C)的集群中,其中一个actor存在于每台机器上,而其他actor则有actorRef到另外两台机器,即:
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)
Run Code Online (Sandbox Code Playgroud)
Actor A执行以下代码:
bRef ! msg1
bRef ! msg2
Run Code Online (Sandbox Code Playgroud)
Actor B在消息处理程序中执行以下代码:
case msg1 =>
cRef ! msg3
aRef ! msg4
Run Code Online (Sandbox Code Playgroud)
Actor C在消息处理程序中执行以下代码:
case msg3 =>
aRef ! msg5
Run Code Online (Sandbox Code Playgroud)
我可以做出以下假设(如果有的话):
演员B在获得msg2之前得到msg1
演员A在获得msg4之前获得msg5
而后续问题可能导致了解上述内容:是否发送了消息!运营商是通过网络真正异步还是等到接收邮箱获得它?即行
bRef ! msg1
Run Code Online (Sandbox Code Playgroud)
阻止,直到演员B在其邮箱中获取消息,或者它是否产生处理传递并继续执行的线程
bRef ! msg2
Run Code Online (Sandbox Code Playgroud)
在它甚至知道演员B得到msg1之前?
对于(1),您可以保证msg1将在msg2之前由调度员排队.一旦他们入队,实际发生的事情实际上取决于你使用的调度员:http://akka.io/docs/akka/1.1.2/scala/dispatchers.html,但在你的情况下,只要B可以同时接受这两个调度员消息然后它将始终在msg2之前接收msg1.
对于(2),不,你没有这个保证.的!一旦调度程序将消息排入队列,方法就会返回,而不是当目标actor的邮箱接受该消息时.然后在另一个线程中完成发送,并受到各种竞争条件的影响.
是由!发送的消息!运营商是通过网络真正异步还是等到接收邮箱获得它?
您可以将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");
Run Code Online (Sandbox Code Playgroud)
打印:
scala> t ! "one"; t ! "two"; t ! "three"; println("Main thread");
Received message
Main thread
scala> Received message
Received message
Run Code Online (Sandbox Code Playgroud)
这意味着在您甚至知道是否将传递消息之前,主线程中的代码执行仍在继续.在这种情况下,如果我们在调度程序上设置了pushTimeout并使Thread.sleep等待超过超时,则消息send很容易超时.
将此与使用!!进行比较:
scala> t !! "one"; t !! "two"; t !! "three"; println("test");
Received message
Received message
Received message
test
Run Code Online (Sandbox Code Playgroud)
所以,考虑到这一点.实现(2)的方法是:
case msg1 =>
cRef !! msg3
aRef ! msg4
Run Code Online (Sandbox Code Playgroud)