Reputation: 1794
Im using Play and have an action in which I want to do two things:-
Since WS API returns a Future
, I'm using Action.async
.
My Redis cache module also returns a Future
.
Assume I'm using another ExecutionContext appropriately for the potentially long running tasks.
Q. Can someone confirm if I'm on the right track by doing the following. I know I have not catered for the Exceptional cases in the below - just keeping it simple for brevity.
def token = Action.async { implicit request =>
// 1. Get Future for read on cache
val cacheFuture = scala.concurrent.Future {
cache.get[String](id)
}
// 2. Map inside cache Future to call web service
cacheFuture.map { result =>
WS.url(url).withQueryString("id" -> result).get().map { response =>
// process response
Ok(responseData)
}
}
}
My concern is that this may not be the most efficient way of doing things because I assume different threads may handle the task of completing each of the Futures.
Any recommendations for a better approach are greatly appreciated.
Upvotes: 1
Views: 242
Reputation: 9168
That's not specific to Play. I suggest you have a look at documentations explaining how Future
s work.
val x: Future[FutureOp2ResType] = futureOp1(???).flatMap { res1 => futureOp2(res1, ???) }
Or with for-comprehension
val x: Future[TypeOfRes] = for {
res1 <- futureOp1(???)
res2 <- futureOp2(res1, ???)
// ...
} yield res
As for how the Future
s are executed (using threads), it depends on which ExecutionContext
you use (e.g. the global one, the Play one, ...).
WS.get
returning aFuture
, it should not be called withincacheFuture.map
, or it will returns aFuture[Future[...]]
.
Upvotes: 3