首页 > 解决方案 > 是否收到询问模式覆盖消息

问题描述

我定义了以下消息和参与者:

case class Message1(text: String)
case class Message2(text: String)
case class Message3(text: String)

class Actor1(actor2: ActorRef) extends Actor {
    def receive = {
        case Message1(text) =>
            (actor2 ? Message2(text)).mapTo[Message3].foreach(self ! _)
        case Message3(text) =>
            println(s"Got the message[$sender]: " + text)
    }
}

class Actor2 extends Actor {
    def receive = {
        case Message2(text) =>
            println(s"Actor2[$self] received: " + text)
            sender ! Message3("Received message1: " + text)
    }
}

def main(args: Array[String]): Unit = {

    val system = ActorSystem("Test")
    system.actorOf(Props(new Actor1(system.actorOf(Props(new Actor2))))) ! Message1("Hello")
}

当我运行此代码时,Actor1 接收到 Message3 时的输出意味着它只接收从 Future.foreach 内部发送的 Message3 而不是 Actor2 发回的 Message3 - 因为这是由询问模式处理的。

所以我的问题是:这总是预期的行为吗?

标签: scalaakka

解决方案


是的,这实际上是预期的行为。

ask 的主要目的是创建一个虚拟的 ActorRef,它不像完全成熟的 Actor 那样使用尽可能多的资源来充当您可以回复的发送者。

它只包装一个在收到消息并从 ask 函数返回未来时完成的承诺。

因此,虽然您在技术上是从 Actor1 询问,但 Actor2 中的 sender() 将是询问创建的虚拟 PromiseActor,这就是您没有收到来自 Actor2 的 Message2 的原因。


推荐阅读