由于Netty是非阻塞服务器,因此将操作更改为使用.async
有什么作用?
def index = Action { ... }
与
def index = Action.async { ... }
我了解使用
.async
会得到一个Future[SimpleResult]
。但是,由于Netty不受阻碍,因此Play会在幕后做类似的事情吗?这将对吞吐量/可扩展性产生什么影响?这是一个很难回答的问题,它取决于其他因素吗?
我问的原因是,我有自己的自定义
Action
,我想为每个页面请求重置cookie超时,所以我这样做是async
调用: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(...))
}
}
摘录自上面的片段是我正在使用
Future[SimpleResult]
,这类似于调用Action.async
,但这在我的Action本身内部吗?我想了解这会对我的应用程序设计产生什么影响。似乎只是为了能够根据每个请求设置Cookie,我已从阻止更改为非阻止。但是由于Netty是非阻塞性的,我感到困惑,也许我还没有真正改变现实,因为它已经异步了?
还是我只是简单地创建了另一个嵌入在另一个异步调用中的异步调用?
希望有人可以用一些细节来澄清这一点,以及这将对性能/吞吐量产生怎样的影响。
最佳答案
def index = Action { ... }
是非阻塞的,您是对的。Action.async
的目的仅仅是使您在操作中使用Futures
更加容易。
例如:
def index = Action.async {
val allOptionsFuture: Future[List[UserOption]] = optionService.findAll()
allOptionFuture map {
options =>
Ok(views.html.main(options))
}
}
在这里,我的服务返回一个
Future
,为避免处理提取结果,我将其映射到Future[SimpleResult]
,其余部分由Action.async
处理。如果我的服务直接返回
List[UserOption]
,则可以使用Action.apply
,但实际上,它仍然是非阻塞的。如果查看
Action
源代码,甚至可以看到apply
最终调用async
:https://github.com/playframework/playframework/blob/2.3.x/framework/src/play/src/main/scala/play/api/mvc/Action.scala#L432
关于scala - 使用Play.async会产生什么效果,因为Play使用非阻塞的Netty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24166136/