Since Netty is a non-blocking server, what effect does changing an action to using .async
?
def index = Action { ... }
versus
def index = Action.async { ... }
I understand that with .async
you will get a Future[SimpleResult]
. But since Netty is non-blocking, will Play do something similar under the covers anyway?
What effect will this have on throughput/scalability? Is this a hard question to answer where it depends on other factors?
The reason I am asking is, I have my own custom Action
and I wanted to reset the cookie timeout for every page request so I am doing this which is a async
call:
object MyAction extends ActionBuilder[abc123] {
def invokeBlock[A](request: Request[A], block: (abc123[A]) => Future[SimpleResult]) = {
...
val result: Future[SimpleResult] = block(new abc123(..., result))
result.map(_.withCookies(...))
}
}
The take away from the above snippet is I am using a Future[SimpleResult]
, is this similar to calling Action.async
but this is inside of my Action itself?
I want to understand what effect this will have on my application design. It seems like just for the ability to set my cookie on a per request basis I have changed from blocking to non-blocking. But I am confused since Netty is non-blocking, maybe I haven't really changed anything in reality as it was already async?
Or have I simply created another async call embedded in another one?
Hoping someone can clarify this with some details and how or what effect this will have in performance/throughput.
def index = Action { ... }
is non-blocking you are right.The purpose of
Action.async
is simply to make it easier to work withFutures
in your actions.For example:
Here my service returns a
Future
, and to avoid dealing with extracting the result I just map it to aFuture[SimpleResult]
andAction.async
takes care of the rest.If my service was returning
List[UserOption]
directly I could just useAction.apply
, but under the hood it would still be non-blocking.If you look at
Action
source code, you can even see thatapply
eventually callsasync
: https://github.com/playframework/playframework/blob/2.3.x/framework/src/play/src/main/scala/play/api/mvc/Action.scala#L432I happened to come across this question, I like the answer from @vptheron, and I also want to share something I read from book "Reactive Web Applications", which, I think, is also great.
It also presented one sample:
which is problematic, given its use of the blocking
java.io.File
API.-
Hope it helps, too.