播放框架Scala在后台运行作业

时间:2017-11-02 20:02:22

标签: scala playframework playframework-2.0

有什么方法可以从控制器触发作业(不等待它完成)并向用户显示作业将在后台运行的消息?

我有一个控制器方法需要很长时间才能运行。所以我想让它离线运行并向用户显示它将在后台运行的消息。

我尝试了Action.async,如下所示。但是Future对象的处理仍然花费更多时间并且超时。

def submit(id: Int) = Action.async(parse.multipartFormData) { implicit request =>
    val result = Future {
      //process the data
    }
   result map {
      res =>
      Redirect(routes.testController.list()).flashing(("success", s"Job(s) will be ruuning in background."))
   }
}

3 个答案:

答案 0 :(得分:3)

您也可以在不以“火灾和遗忘”的方式等待未来结果的情况下返回结果

def submit(id: Int) = Action(parse.multipartFormData) { implicit request =>     
    Future {
      //process the data
    }
    Redirect(routes.testController.list()).flashing(("success", s"Job(s) will be running in background."))
}

答案 1 :(得分:0)

docs州:

  

通过给出Future [Result]而不是普通Result,我们可以快速生成结果而不会阻塞。一旦兑换承诺,Play将立即提供结果。

     

等待响应时将阻止Web客户端,但服务器上不会阻止任何内容,服务器资源可用于为其他客户端提供服务。

您可以将客户端代码配置为使用ajax请求,并在页面的某些部分显示 Waiting for data 消息,而不会阻止其他网页加载。

答案 2 :(得分:0)

我也试过了“Futures.timeout”选项。它似乎工作正常。但我不确定它的正确方法。

result.withTimeout(20.seconds)(futures).map { res =>
  Redirect(routes.testController.list()).flashing(("success", s"Job(s) will be updated in background."))
}.recover {
  case e: scala.concurrent.TimeoutException =>
    Redirect(routes.testController.list()).flashing(("success", s"Job(s) will be updated in background."))
}