Spray.io - 将处理委托给另一个演员

时间:2014-04-23 20:43:30

标签: scala akka spray

我使用Spray.io框架实现REST服务。此类服务必须接收一些“搜索”查询,处理它们并将结果发送回客户端。执行搜索的代码位于单独的actor - SearchActor中,因此在从用户接收(JSON)查询后,我将此查询重新发送(使用ask模式)到我的SearchActor。但是我真的不明白它是如何实现spray.io route actor和我的SearchActor之间的交互。

我在这里看到了几个变体但哪一个更正确,为什么?

  1. 在启动时创建一个SearchActor实例,并将每个请求发送给此actor
  2. 为每个请求创建新的SearchActor实例
  3. 在启动时创建SearchActor actor池并将请求发送到此池

2 个答案:

答案 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/