我对 Akka 很陌生,在引用手册中找不到答案。
假设我们在 3 台机器(A、B、C)的集群中分布了远程角色,其中一个角色位于每台机器上,其他角色拥有另外 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)
Actor A 执行以下代码:
bRef ! msg1
bRef ! msg2
Actor B 在消息处理程序中执行以下代码:
case msg1 =>
cRef ! msg3
aRef ! msg4
Actor C 在消息处理程序中执行以下代码:
case msg3 =>
aRef ! msg5
我可以做以下假设吗(如果有的话):
以及可能导致理解上述内容的后续问题:
是消息发送的!运营商通过网络真正异步还是等到接收邮箱得到它?
IE。行吗
bRef ! msg1
阻塞直到参与者 B 在其邮箱中收到消息或它是否产生处理传递的线程并继续执行
bRef ! msg2
在它知道 Actor B 得到 msg1 之前?
最佳答案
对于 (1),您可以保证 msg1 将在 msg2 之前由调度程序入队。排队后实际发生的情况实际上取决于您使用的调度程序:http://akka.io/docs/akka/1.1.2/scala/dispatchers.html ,但在你的情况下,只要 B 可以接受这两条消息,那么它总是会在 msg2 之前收到 msg1。
对于(2),不,您没有此保证。这 !方法在调度程序将消息入队后立即返回,而不是在目标参与者的邮箱接受消息时返回。发送然后在另一个线程中完成,并受到各种竞争条件的影响。
Is message sent by the ! operator through the network truly asynchronously or does it wait until the receiving mailbox gets it?
您可以将 BoundedMailbox 与本地参与者一起使用,以显示将消息排队发送到调度程序与 ! 异步:
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
关于scala - akka actor 中的消息传递序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6201667/