Spray 的 `detach` 指令

Spray's `detach` Directive

给定以下 Spray 代码:

object Main extends App with SimpleRoutingApp {

  implicit val system = ActorSystem("my-system")

  val pipeline: HttpRequest => Future[String] = sendReceive ~> unmarshal[String]

  startServer(interface = "localhost", port = 8080) {
    path("go") {
      get { 
        detach() { 
          complete {
            val req = Post("http://www.google.com") ~> addHeader("Foo", "bar")
            pipeline(req).recoverWith[String]{ case _ => Future { "error!" } }
          }
        }
      }
    } 
  }
}

我将 complete 函数放在 detach 指令中。

文档解释说 detach 将:execute the inner route inside a future.

使用(或不使用)detach 的意义是什么 - 从 性能 的角度来看?

我看了这个相关的answer,不过重点是如何使用detach。

如果没有 detach,spray 将一个接一个地处理所有请求,而如果有 detach,它将并行处理它们。如果你可以并行处理这个请求,你最好使用 detach 以获得更好的性能。

detach 通常是必需的,因为路由在 actor 中同步运行。这意味着当 HttpRequest 被路由时,actor 不能同时处理任何其他消息。

但是,异步路由位(例如使用 Future 完成或使用 FutureDirectives 之一也会释放原始路由参与者以用于新请求。

因此,在路由本身成为瓶颈或您同步完成请求的情况下,添加 detach 可能会有所帮助。在你上面的例子中,你已经完成了一个 Future 并且有一个相对简单的路由结构,在这种情况下添加 detach 不会有太大帮助(或者甚至可能引入一点点延迟)。

此外,detach 存在一些不一致之处,您可以在此处阅读:

使用 detach 的替代方法是使用按请求执行者。

在 akka-http 中,路由是在 Futures 之上实现的,尽可能异步并且不再局限于 actor,因此不需要 detach 并因此被删除。