我的目标是从异步控制器中进行一些数据库查询,然后返回答案。
我正在处理示例项目,目前仅通过睡眠来模拟数据库查询,但是我注意到的是,无论我做什么,REST接口甚至不会在第二个查询开始之前就开始第二个查询的睡眠。一完成。 例如:如果我从浏览器的一个选项卡调用REST接口,然后再从另一个选项卡调用1秒钟,我希望第二个也能在10秒内得到答复,但实际上是19秒。
而且似乎也没有使用“ database-io”池:
1:application-akka.actor.default-dispatcher-2
2:application-akka.actor.default-dispatcher-5
我的代码:
@Singleton
class AsyncController @Inject()(cc: ControllerComponents, actorSystem: ActorSystem) extends AbstractController(cc) {
implicit val executionContext = actorSystem.dispatchers.lookup("database-io")
def message = Action.async {
getFutureMessage().map { msg => Ok(msg) }
}
private def getFutureMessage(): Future[String] = {
val defaultThreadPool = Thread.currentThread().getName;
println(s"""1: $defaultThreadPool""")
val promise: Promise[String] = Promise[String]()
actorSystem.scheduler.scheduleOnce(0 second) {
val blockingPool = Thread.currentThread().getName;
println(s"""2: $blockingPool""")
Thread.sleep(10000)
promise.success("Hi!")
}(actorSystem.dispatcher)
promise.future
}
}
答案 0 :(得分:0)
此行为可能是两个原因:
答案 1 :(得分:0)
您需要避免阻塞代码。基本上:
您可以使用一种返回Future的方法。
您映射到其中。
您可以恢复AppName
结果可能带来的任何失败。
让我说:
Future
然后将其映射到其中:
def userAge (userId: String): Future[Int] = ???
请注意,如果您有多个通话,则另一个userAge.map{
age => ??? //everything is ok
}.recover{ case e: Throwable => ??? //Do something when it fails
会变成map
,因为您想要flatMap
而不是Future[...]
。