将我的阻塞播放/scala/slick 算法更改为不阻塞

Changing my blocking play / scala /slick algorithm not to block

这是一个相对简单的问题,我确信我遗漏了一些基本的东西。

因此,从 1,2,3,4,5 的潜在系列中,我可能会从数据库查询中得到 2、4、5。此代码添加了 1 和 3...但我的理解是它会阻止所有内容,这有点顽皮。

对于我所尝试的一切,我无法在未来找到如何让 .diff 方法(这看起来是最干净的策略)在 'Future'、非阻塞上下文中运行。

我是不是漏掉了什么?

这里你只有一个 Future,你不需要创建多个 Await.result。 您可以通过切换到 Action.async:

来摆脱所有 Await.result(...) 电话
Action.async {
  val allYear = (1 to 10000).toSet
  val intermediate:Future[String] = for (
    res <- db.run(filterAnnualPerilAndRegionFillGaps(peril, region).result)
  ) yield (
    header + res.mkString("\n") + "\n" + 
    allYear.diff(res.map (s => s.year).toSet).map(s => new SingleEventYear(region, peril, 0 ,0 , s, 0)).mkString("\r\n")
  )
  intermediate.map(item => Ok(item))
}

这是如何执行此操作的另一个示例:

def annualAtomTesting(peril: String, region: String) = Action.async {
  for {
    results <- db.run(filterAnnualPerilAndRegionFillGaps(peril, region).result)
    years = results.map(_.year).toSet
    allYears = (1 to 10000).toSet
    differences = allYears diff years
    missing = differences.map(new SingleEventYear(region, peril, 0, 0, _, 0))
    intermediate = header + results.mkString("\n") + "\n" + missing.mkString("\r\n")
  } yield Ok(intermediate)
}

您不应在生产代码中使用 Await。 Play 允许您使用需要 return Future[Result] 而不是 Result.

的异步操作

如果你真的想用 await 考虑你的代码,你可以像这样使用 scala async:

import scala.async.Async._
def annualAtomTesting(peril: String, region: String) = Action.async {
  async {
    val results: Seq[SingleEventYear] = await(db.run(filterAnnualPerilAndRegionFillGaps(peril, region).result))
    val years = results.map(_.year).toSet
    val allYears = (1 to 10000).toSet
    val differences = allYears diff years
    val missing = differences.map(new SingleEventYear(region, peril, 0, 0, _, 0))
    val intermediate = header + results.mkString("\n") + "\n" + missing.mkString("\r\n")
    Ok(intermediate)
  }
}

您可以在 async 块中的任何 Future 上调用 await,它将 return 结果,也许这种方法看起来更简单,但它有局限性。它将使用宏更改为 flatMaps。 async { Ok("res") } 是类型 Future[Result] 的表达式。这允许您将它放在 Action.async {} 中并使您的代码保持异步。