Scala Playframework非阻塞动作

Scala Playframework非阻塞动作,scala,playframework,akka,Scala,Playframework,Akka,遇到一个问题,我还没有找到答案 使用Scala在playframework 2上运行 需要编写执行多个未来调用的操作方法。 我的问题: 1) 附加的代码是非阻塞的,因此看起来应该是这样的吗? 2) 是否可以保证在任何给定时间捕获两个DAO结果 def index = Action.async { val t2:Future[Tuple2[List[PlayerCol],List[CreatureCol]]] = for { p <- PlayerDAO.findAll()

遇到一个问题,我还没有找到答案

使用Scala在playframework 2上运行

需要编写执行多个未来调用的操作方法。 我的问题: 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)))
}
def index=Action.async{
val t2:Future[Tuple2[List[PlayerCol],List[creatercol]]]=for{
P
附加的代码是非阻塞的,因此看起来应该是这样的吗

这取决于几件事。首先,我将假设
PlayerDAO.findAll()
creatoredao.findAlive()
return
Future[List[PlayerCol]]
Future[List[creatorecol]]
分别。最重要的是这些函数实际调用的是什么。它们是进行JDBC调用,还是使用异步DB驱动程序

如果答案是JDBC(或其他同步db驱动程序),那么您仍然是阻塞的,并且没有办法使其完全“非阻塞”。为什么?因为JDBC调用会阻止它们当前的线程,而将它们包装在
未来的
中并不能解决这一问题。在这种情况下,您最多可以让它们阻止一个不同于播放用来处理请求的
ExecutionContext
。这通常是一个好主意,因为如果有多个db请求同时运行实际上,它们可以阻止Play用于处理HTTP请求的内部线程池,而突然之间,您的服务器将不得不等待处理其他请求(即使它们不需要数据库调用)

有关不同
ExecutionContext
s的更多信息,请参阅和

如果您的答案是一个异步数据库驱动程序,比如reactive mongo(也有类似scalike的jdbc,可能还有其他一些),那么您的状态很好,我可能让您读得比必须读的多一点。在这种情况下,您的
index
控制器功能将是完全无阻塞的

是否可以保证在任何给定时间捕获两个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)))
}
我不太清楚这是什么意思。在您当前的代码中,实际上是按顺序进行这些调用。
createrDao.findAlive()
直到
PlayerDAO.findAll()才会执行
已返回。由于它们彼此不依赖,因此这似乎不是有意的。要使它们并行运行,您应该在将它们映射到中之前实例化
未来的
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)))
}
def index=Action.async{
val玩家:Future[List[PlayerCol]=PlayerDAO.findAll()
val bioters:Future[List[CreatureCol]=CreatureDAO.findAlive()
val t2:Future[(列表[PlayerCol],列表[CreatureCol])]=for{
P
附加的代码是非阻塞的,因此看起来应该是这样的吗

这取决于几件事。首先,我将假设
PlayerDAO.findAll()
creatoredao.findAlive()
return
Future[List[PlayerCol]]
Future[List[creatorecol]]
分别。最重要的是这些函数实际调用的是什么。它们是进行JDBC调用,还是使用异步DB驱动程序

如果答案是JDBC(或其他同步db驱动程序),那么您仍然是阻塞的,并且没有办法使其完全“非阻塞”。为什么?因为JDBC调用会阻止它们当前的线程,而将它们包装在
未来的
中并不能解决这一问题。在这种情况下,您最多可以让它们阻止一个不同于播放用来处理请求的
ExecutionContext
。这通常是一个好主意,因为如果有多个db请求同时运行实际上,它们可以阻止Play用于处理HTTP请求的内部线程池,而突然之间,您的服务器将不得不等待处理其他请求(即使它们不需要数据库调用)

有关不同
ExecutionContext
s的更多信息,请参阅和

如果您的答案是一个异步数据库驱动程序,比如reactive mongo(也有类似scalike的jdbc,可能还有其他一些),那么您的状态很好,我可能让您读得比必须读的多一点。在这种情况下,您的
index
控制器功能将是完全无阻塞的

是否可以保证在任何给定时间捕获两个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)))
}
我不太清楚这是什么意思。在您当前的代码中,实际上是按顺序进行这些调用。
createrDao.findAlive()
直到
PlayerDAO.findAll()才会执行
已返回。由于它们彼此不依赖,因此这似乎不是有意的。要使它们并行运行,您应该在将它们映射到中之前实例化
未来的
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)))
}
def index=Action.async{
val玩家:Future[List[PlayerCol]=PlayerDAO.findAll()
val bioters:Future[List[CreatureCol]=CreatureDAO.findAlive()
val t2:Future[(列表[PlayerCol],列表[CreatureCol])]=for{

p非常感谢。我确实在使用反应式Mongo,因此感谢您的评论。非常感谢。我确实在使用反应式Mongo,因此感谢您的评论。