【问题标题】:Spray's `detach` DirectiveSpray 的 `detach` 指令
【发布时间】:2015-07-12 04:37:23
【问题描述】:

给定以下喷涂代码:

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。

【问题讨论】:

    标签: scala spray


    【解决方案1】:

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

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

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

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

    使用 detach 的替代方法是使用 per-request-actors。

    在 akka-http 中,路由是在 Futures 之上实现的,以尽可能异步且不再局限于某个参与者,因此不需要 detach,因此已将其删除。

    【讨论】:

    • 试图理解你的前几句话 - 不会在 route 内部使用 detach 和调用 Await.result 导致一次只处理一个 HTTP 请求,即同时由网络应用?
    • 也在这里回答:是的,这是真的。如果没有使用异步指令,路由结构中的阻塞将阻止异步路由处理。
    • 谢谢!我只发布了该 Google 群组链接,因为其他人会发现您的帖子有帮助!
    【解决方案2】:

    不分离喷雾将一一处理所有请求,而分离它会并行处理它们。如果您可以并行处理这些请求,则最好使用 detach 以获得更好的性能。

    【讨论】:

    • 你的意思是,如果没有detach,spray web-server 将一次处理一个 HTTP 请求,即它不能同时处理多个请求?能否提供出处?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 2015-12-16
    • 1970-01-01
    • 2013-10-18
    相关资源
    最近更新 更多