与 Spray、Akka 和 actorSelect 的异步操作



我在使用 spray 时一直遇到同样的设计问题,即在 Akka 中执行一些异步(tell)操作后,如何找到请求的 Spray http 请求的原始上下文。

我正在使用每个请求模型的 Net-a-Porter actor。它创建一个子参与者,我指定该子参与者来处理每个请求,该子参与者由另一个持有正确请求上下文的参与者封装。

让我们称我的演员为 ActorA,它上面有这个接收方法:

def receive: Receive = {
 case v : InputJson =>
   val id = createId
   val redisList = context.actorOf(Props[RedisListActor])
   // At this point, sender is the 'per-request' actor created, which has the HTTP context of the Spray request.
   redisList ! ListRequest(id, sender.path.toStringWithoutAddress, v)

这是将输入添加到 redis 上的作业队列中,该队列在另一台服务器上使用。完成此作业后,另一个服务器会将结果添加到我们订阅的 Redis PubSub 队列中。当一个项目进入这个队列时,它会提醒我的ActorA(使用context.actorOf)。

case kr : KubernetesReply =>
  context.system.actorSelection(kr.actorPath) ! TaskResponse("Success", kr.payload, kr.id)

你可以看到我试图通过使用它的 actorPath 来找到原始发送者,但在 KubernetesReply 上,我发现该路径是 deadLetters(即使我没有明确杀死请求 actor)。我已经确认这是正确的路径(即我可以从 InputJson 处理程序发回任务响应)。

正确的模式是什么?我怎样才能找到原来的演员,为什么它消失了?

您可以直接在ListRequest消息中放置ActorRef

case class ListRequest(id: YourIdType, requestActor: ActorRef, json: InputJson)
def receive: Receive = {
  case v : InputJson =>
    val id = createId
    val redisList = context.actorOf(Props[RedisListActor])
    redisList ! ListRequest(id, sender, v)
  case kr : KubernetesReply =>
    kr.requestActor ! TaskResponse("Success", kr.payload, kr.id)
}

最新更新