Akka Ask&期货

时间:2015-04-28 16:07:31

标签: akka spray

我是akka noob所以道歉!

我正在玩一个使用Spray和Akka的系统。 我使用以下代码段将消息发送给另一个actor。 它使用ask,根据我的理解,它将返回一个在" mapTo"中解决的未来。和" map"。然后我使用Sprays"完成"将结果返回给用户。指令。

val response = (worker ? Create(json))
            .mapTo[Ok]
            .map(result => s"I got a response: ${result}")
            .recover { case _ => "error" }

complete(response)

我的问题是,既然这是未来,我是否需要担心向客户发送正确的回复?在一些代码示例中,我看到了回复的actorRef作为请求的一部分发送的示例......

// set reply to actor
val replyTo = sender() // important to not close over sender()

// create actor that collects replies from workers
val aggregator = context.actorOf(Props(
    classOf[StatsAggregator], words.size, replyTo))

然后在接收演员......

replyTo ! SendResult

我应该通过" replyTo"作为请求的一部分的演员还是这个都在mapTo中处理?

提前致谢!

1 个答案:

答案 0 :(得分:1)

complete指令将向您的服务的http / https客户端发回回复。你不需要做更多的事情。请注意,您的代码会在未来通过recover来吞下错误。 Spray会将其视为成功,并将返回状态代码200

最后也是最重要的是,您的工作人员必须像这样回复Ok消息。

class Worker extends Actor {
    def receive: Receive = {
        case Create(json) => 
        //do some staff with json
        sender() ! Ok // This Ok message will be passed in the future in spray route
    }
}

只有当员工在内部使用Future来处理工作量时,才需要replyTo成语。如下例所示

class Worker extends Actor {
    def recieve: Recieve = {
        case Create(json) => 
            val future = Future{
                //do some staff with json
            }

            val replyTo = sender()

            future.onComplete {
                case scala.util.Success(result) => 
                    replyTo ! Ok
                case scala.util.Failure(ex) => 
                    replyTo ! akka.actor.Status.Failure(ex)    
            }
    }
}

需要replyTo来修复消息的实际发送者,因为onComplete可以在不同的actor上下文中执行,该上下文可以指向不同的发送者,从而导致消息被发送给错误的actor。