首页 > 解决方案 > akka actor 可以在不同的情况下回复消息吗

问题描述

我正在使用 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), 和另一个演员发送消息但没有回复,只有当我在下面添加一些回复(案例 M1)它才能M2工作AnswerActor

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

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

标签: akkaactorakka-http

解决方案


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

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

import akka.pattern.pipe

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

如果您想忽略(或隐藏)除 之外的每条消息MyReply,则可以立即使用context.become来安装一个新的消息处理程序,该处理程序可以根据需要忽略/隐藏。

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

的使用Await.result也可能直接导致您的问题,具体取决于可用的内核/vCPU 数量和 Akka 版本:阻塞可能会阻止任何参与者或流阶段获得 CPU 时间。


推荐阅读