akka演员可以在不同的情况下回复消息吗

Could akka actor reply message in different case

我正在使用 Akka HTTP 并且有一个 AnswerActor,我想做以下事情。

class AnswerActor() extends Actor {
  var requestMap = mutable.Map[String, ActorRef]()
  ...
  override def receive: Receive = {
// I want to store sender() here instead of reply in this case, because my reply is not available at this moment
    case message: M1 => requestMap.put(sender().path.name -> sender()) 

// I want to reply when I receive M2, my reply is available now
    case message: M2 => requestMap.get(...) ! MyReply 

我使用 val ans = Await.result(questionActor ? M1) 和另一个演员发送消息 M2AnswerActor 但是没有回复,只有我在下面添加一些回复(案例 M1)它可以工作

case message: M1 => requestMap.put(name -> sender())
    sender() ! something

是否可以在akka中实现上述逻辑?

根据您有限的描述,我怀疑 M2 在收到 M1 后没有被 questionActor 收到(或者至少在收到 M1 之后没有收到要求超时)。一般来说,无论 C 是在 A 之前还是之后发送消息,都不能保证从 actor A 发送到 actor B 的消息会在从 actor C 发送到 actor B 之前收到(顺序保证是如果 actor A将消息 1 然后 2 然后 3 发送给 actor B,在收到 1 或 2 之前不会收到 3,在收到 1 之前不会收到 2)。

一般来说,在 actor 或流中使用 Await 不是一个好主意,因为这会阻止 actor 处理任何消息。在 actor 中,最好使用管道模式:

import akka.pattern.pipe

(questionActor ? M1).pipeTo(context.self)

如果您想忽略(或隐藏)MyReply 以外的所有消息,您可以立即使用 context.become 安装一个新的消息处理程序,ignores/stashes 根据需要。

在流中,通常最好使用 mapAsync 或在某些情况下(仅限 Akka 2.6.x)ask 流阶段以非-阻塞方式。

Await.result 的使用也可能直接导致您的问题,具体取决于有多少 cores/vCPUs 可用和 Akka 版本:阻塞可能会阻止任何 actor 或流阶段获得 CPU时间。