繁体   English   中英

创建多个期货时,Play框架动作响应被延迟

[英]Play framework action response delayed when creating multiple futures

在以下操作中,它应该在击中URL后立即返回响应,但要等到所有Future模块启动后才发送响应。 即使点击URL后立即记录了“从操作返回”,它也会一直等到“正在启动第10组”被记录在控制台中。

def test = Action { implicit request =>
    Future.successful(0 to 150).foreach { items =>
      items.grouped(15).zipWithIndex.foreach{ itemGroupWithIndex =>
        val (itemGroup, index) = itemGroupWithIndex
        Future {
          logger.info("************** Starting for group " + index)
          itemGroup.foreach { item =>
            Thread.sleep(1000)
            logger.info("Completed for item " + item)
          }
        }
      }
    }
    logger.info("************** Returning from action **************")
    Ok(views.html.test("test page"))
}

我无法理解此延迟背后的原因,如何使该操作立即发送响应。

播放框架版本2.5.9

您的操作不是异步的。 您有一个同步端点,这就是为什么您立即在控制台上看到“ Returning from action”的原因。 您可能应该使用Action.async作为处理类型。 使用异步操作将大大提高应用程序的整体性能,强烈建议在构建高吞吐量和响应式Web应用程序时使用。

代码中的两点需要更改

  1. 异步动作 :因为您使用的是Future,所以该动作应该是异步的: Action.async{...}

  2. 无阻塞代码 :使用Future和异步编程的全部目的是不要拥有“阻塞”执行的代码。 因此,我建议删除代码的Thread.sleep(1000)部分。

请注意,如果您以非阻塞方式编写代码; 每当动作方法得到结果时; 它将执行所需的操作,例如记录日志或提供视图。

这是因为您的期货中存在竞争条件。

您需要确保返回的是单个Future[T]而不是Future[Future[T]] (或任何分层的方差)。

如果期货彼此独立,请使用Future.sequence

例:

 def future: Future[String] = Future.successful("hi")


 def action = Action.async { _ =>
   val futures: Seq[Future[String]] = (1 to 50).map(_ => future()).toSeq
   val oneFuture = Future.sequence(futures)
   oneFuture
 }

这样可以避免比赛条件

仅供参考,这与Play框架无关。 这是Scala中的并发编程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM