1

Given the following Spray code:

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!" } }
          }
        }
      }
    } 
  }
}

I put the complete function within the detach directive.

The docs explain that detach will: execute the inner route inside a future.

What's the significance of using (or not) detach - from a performance perspective?

I looked at this related answer, but it focuses on how to use detach.

Community
  • 1
  • 1
Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384

2 Answers2

4

detach is usually needed because routing runs synchronously in an actor. This means that while an HttpRequest is routed, the actor cannot process any other messages at the same time.

However, routing bits that are asynchronous like completing with a Future or using one of the FutureDirectives will also free the original routing actor for new requests.

So, in cases where routing itself is the bottleneck or you complete a request synchronously, adding detach may help. In your case above, you already complete with a Future and have a relatively simple routing structure in which case adding detach won't help much (or may even introduce a tiny bit of latency).

Also, detach comes with some inconsistencies you can read about here:

An alternative to using detach is using per-request-actors.

In akka-http, routing is implemented on top of Futures to be as asynchronous as possible and not confined to an actor any more so that detach isn't needed and was removed therefore.

jrudolph
  • 8,307
  • 4
  • 32
  • 50
  • Trying to understand your first few sentences - will not using `detach` and calling `Await.result` inside of the `route` result in only a single HTTP Request being handled at a time, i.e. simultaneously by the web app? – Kevin Meredith Jul 13 '15 at 12:41
  • To answer here as well: yes, that's true. If there are no asynchronous directives used, blocking in the route structure will prevent asynchronous route processing. – jrudolph Jul 13 '15 at 14:51
  • Thanks! I only posted that Google groups link since others will find your post there helpful! – Kevin Meredith Jul 13 '15 at 15:02
0

Without detach spray will process all requests one by one, while with detach it'll process them parallel. If you can process this requests in parallel, you'd better use detach for better performance.

Dmitry Meshkov
  • 921
  • 7
  • 20
  • You're saying that, without `detach`, the spray web-server will process HTTP requests one at a time, i.e. it can't handle more than 1 request simultaneously? Could you please provide a source? – Kevin Meredith Jul 13 '15 at 02:04