scala - akka actor 中的消息传递序列

标签 scala messages actor akka mq

我对 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

我可以做以下假设吗(如果有的话):
  • Actor B 在得到 msg2 之前先得到 msg1
  • Actor A 在得到 msg4 之前先得到 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/

    相关文章:

    api - 存档来自 Twitter 的直接消息

    Scala:为什么Actors 是轻量级的?

    java - Play Framework 2.0 中的文件大小限制

    scala - Akka 和案例陈述

    java - 属性文件中的选择模式

    scala - 将消息传递给远程参与者时出现未知 UID 警告

    scala - 值(value) !不是 Actor 的成员

    scala - 什么是事件驱动的并发?

    java - 我如何用scala代码编译java记录?

    android - 在 Android 上丢失上下文时如何保存 OpenGL 纹理