Use Future in Spray Routing
akka, scala, spray
Solution
You can use the `onSuccess` directive:
get {
optionalCookie("commToken") { cookie =>
//....
val response = (MTurkerProgressActor ? Register).mapTo[..].map({...})
onSuccess(response) {
case (result, mTurkerResponse) =>
setCookie(HttpCookie("commToken", content = mTurkerResponse.mturker.get.commToken)) {
complete(result, mturkerResponse.mturker.get)
}
}
}
There's also `onFailure` and `onComplete` (for which you have to match on `Success` and `Failure`) See http://spray.io/documentation/1.2.1/spray-routing/future-directives/onComplete/
Also, instead of using `get` directly it's much more idiomatic to use `map` (I assume the `mturker` is an `Option` or something similar):
case (result, mTurkerResponse) =>
mTurkerResponse.mturker.map { mt =>
setCookie(HttpCookie("commToken", content = mt.commToken)) {
complete(result, mt)
}
}
Problem
I'm new to asynchronous programming. I read this tutorial http://danielwestheide.com/blog/2013/01/09/the-neophytes-guide-to-scala-part-8-welcome-to-the-future.html and was surprised by how effortless I can incorporate Future into the program. However, when I was using Future with Routing, the return type is kind of wrong. ``` get { optionalCookie("commToken") { case Some(commCookie) => val response = (MTurkerProgressActor ? Register).mapTo[..].map({...}) val result = Await.result(response, 5 seconds) setCookie(HttpCookie("commToken", content = result._2.mturker.get.commToken)) { complete(result._1, result._2.mturker.get) } case None => // ... } } ``` I really don't want to use `Await` (what's the point of asynchronous if I just block the thread and wait for 5 seconds?). I tried to use `for`-comprehension or `flatMap` and place the `setCookie` and `complete` actions inside, but the return type is unacceptable to Spray. For-comprehension returns "Unit", and `flatMap` returns a Future. Since I need to set up this cookie, I need the data inside. Is `Await` the solution? Or is there a smatter way?