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.
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.
detach
is usually needed because routing runs synchronously in an actor. This means that while anHttpRequest
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 theFutureDirectives
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 aFuture
and have a relatively simple routing structure in which case addingdetach
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.