我在使用 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)
}