喜欢询价和期货

Akka Ask & Futures

我是 akka 菜鸟,所以很抱歉!

我正在玩一个使用 Spray 和 Akka 的系统。 我正在使用以下代码片段向另一个演员发送消息。 它使用 ask which,据我了解 return 一个在 "mapTo" 和 "map" 中解决的未来。然后我 return 使用 Sprays "complete" 指令将结果发送给用户。

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" actor 作为请求的一部分传递,还是这一切都在 mapTo 中处理?

提前致谢!

complete 指令将向您服务的 http/https 客户端发回响应。您不需要做更多的事情。请注意,您的代码通过对未来进行 recover 来吞噬错误。 Spray 会将其视为成功并将 return 状态代码 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
    }
}

仅当 worker 在内部使用 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 可能在不同的参与者上下文中执行,该上下文可能指向不同的发送者,导致消息被发送到错误的参与者.