Tho*_*aus 0 scala akka playframework
碰到一个问题我还没找到答案.
使用Scala在playframework 2上运行.
需要编写一个执行多个Future调用的Action方法.我的问题:1)附加的代码是否是非阻塞的,因此看起来应该如何?2)是否保证在任何给定时间都捕获两个DAO结果?
def index = Action.async {
val t2:Future[Tuple2[List[PlayerCol],List[CreatureCol]]] = for {
p <- PlayerDAO.findAll()
c <- CreatureDAO.findAlive()
}yield(p,c)
t2.map(t => Ok(views.html.index(t._1, t._2)))
}
Run Code Online (Sandbox Code Playgroud)
感谢您的反馈意见.
附加的代码是否是非阻塞的,因此看起来应该是这样的?
这取决于一些事情.首先,我要假设PlayerDAO.findAll()和CreatureDAO.findAlive()返回Future[List[PlayerCol]]和Future[List[CreatureCol]]分别.最重要的是这些功能实际上是自称的.他们是在进行JDBC调用,还是使用异步数据库驱动程序?
如果答案是JDBC(或其他一些同步数据库驱动程序),那么你仍然在阻塞,并且没有办法让它完全"非阻塞".为什么?因为JDBC调用会阻止它们当前的线程,并且将它们包装在一个Future将无法修复它.在这种情况下,您可以做的最多就是让它们阻止ExecutionContext与Play用于处理请求的块不同.这通常是个好主意,因为如果你有几个并发运行的db请求,它们可以阻止用于处理HTTP请求的Play内部线程池,突然你的服务器必须等待处理其他请求(即使它们不需要)数据库调用).
有关不同ExecutionContexts的更多信息,请参阅线程池文档和此答案.
如果你的答案是一个异步数据库驱动程序,如反应性mongo(也有scalike-jdbc,也许还有其他一些),那么你的状态很好,我可能会让你读到比你更多的东西.在那种情况下,您的index控制器功能将完全无阻塞.
是否可以保证在任何给定时间捕获两个DAO结果?
我不太清楚你的意思.在您当前的代码中,您实际上是按顺序进行这些调用.返回CreatureDAO.findAlive()后才执行PlayerDAO.findAll().由于它们不相互依赖,似乎这不是故意的.要使它们并行运行,您应该Future在将它们映射到for-comprehension之前实例化s:
def index = Action.async {
val players: Future[List[PlayerCol]] = PlayerDAO.findAll()
val creatures: Future[List[CreatureCol]] = CreatureDAO.findAlive()
val t2: Future[(List[PlayerCol], List[CreatureCol])] = for {
p <- players
c <- creatures
} yield (p, c)
t2.map(t => Ok(views.html.index(t._1, t._2)))
}
Run Code Online (Sandbox Code Playgroud)
关于完成两个结果,你唯一可以保证的是,yield在Futures完成之前(或者从不,如果它们失败)t2.map(...)不会执行,同样在t2完成之前不会执行主体.
进一步阅读:
在Play Framework 2.2中使用非异步操作有什么好处吗?
| 归档时间: |
|
| 查看次数: |
172 次 |
| 最近记录: |