我使用Spray.io框架实现REST服务。此类服务必须接收一些“搜索”查询,处理它们并将结果发送回客户端。执行搜索的代码位于单独的actor - SearchActor中,因此在从用户接收(JSON)查询后,我将此查询重新发送(使用ask模式)到我的SearchActor。但是我真的不明白它是如何实现spray.io route actor和我的SearchActor之间的交互。
我在这里看到了几个变体但哪一个更正确,为什么?
答案 0 :(得分:2)
你没有被迫使用提问模式。 实际上,它会为你的每个请求创建一个线程,这可能不是你想要的。我建议您改用tell
。您可以通过为每个请求(比线程更便宜)生成新的Actor
来执行此操作,该请求在其构造函数字段之一中具有RequestContext
。您将使用此上下文来回复响应,通常使用其complete
方法。
示例代码。
class RESTActor extends HttpService {
val route = path("mypath") ~ post {
entity(as[SearchActor.Search]) { search => ctx =>
SearchActor(ctx) ! search
}
}
}
case class SearchActor(ctx: RequestContext) {
def receive = {
case msg: Search => //... search process
case msg: Result => ctx.complete(msg) // sends back reply
}
}
答案 1 :(得分:1)
在初始实现之后,变体#1是不可能的 - 你想要扩展,所以单个阻塞actor是坏的。
变体#2和#3差别不大 - 新演员的创作很便宜并且开销很小。由于你的演员可能经常死亡(即后端不可用),我会说#2是要走的路。
具体实施理念显示在http://techblog.net-a-porter.com/2013/12/ask-tell-and-per-request-actors/