多个数据库访问,多个Akka.futures VS在单个Future中包装数据库访问

时间:2012-12-07 09:53:23

标签: playframework-2.0 akka

由于我第一次使用Play 2进行开发,我发现我在控制器中做了很多这样的事情(一个更简单的例子):

 val promUser = Akka.future(UserService.findByUsername(access.username))
  Async(
    promUser.map {
      _.map{
        user => {
          val promService = Akka.future(ServiceService loadOnlyWithUser (id,user.id.get))
          Async(
            promService.map { _.map { service =>
              Ok(toJson(service))
            }.getOrElse(BadRequest("not accessible"))}
          )
        }
      }.getOrElse {
        BadRequest("unauthorised")
      }
    }
  )

拥有单一的未来会更好吗?例如:

val promService = Akka.future{
    val userOption = UserService.findByUsername(access.username)
    userOption.map( user => {
      ServiceService loadOnlyWithDeveloper (id,user.id.get)
    }).getOrElse(None)

  }
  Async(
    promService.map { _.map { service =>
      Ok(toJson(service))
    }.getOrElse(BadRequest("unauthorised"))}
  )

我一方面考虑到控制器的许多期货/回报可能会增加开销,在一个未来的组中,对一个未来的调用将更具可读性,但会导致在Akka系统中运行更大的“线程”。对于更大的工作,我有一个额外的Akka系统,所以这些只包含最多4个SQL事务。至于我可以从apache工作台上解决,上面的例子之间没有任何区别......我有什么遗漏吗?

1 个答案:

答案 0 :(得分:3)

与您的示例相比,性能没有任何差异,因为它们是等效的。

当你写:

val promUser = Akka.future(UserService.findByUsername(access.username))

它不会开始评估Future,它只会在您映射它时执行。

据我了解,你需要考虑期货构成。这是一个非常好的文档,我建议:http://docs.scala-lang.org/sips/pending/futures-promises.html

如果您需要按顺序执行一系列查询,那么如果您有多个Futures,每个数据库访问一个,我认为它不会产生影响。例如。检索记录,然后将其删除。

你可以利用Futures(除了让你的应用程序无阻塞之外)是利用for-comprehension语法,这样你就可以同时运行两个或更多个异步Futures,例如

for {
  authUser <- User.findById(request.authUserId)
  otherUser <- User.findById(id)
} yield (authUser, otherUser)

另外,我建议您使用flatMap一起撰写期货,而不是使用多个Async{}块。这样,您就可以有效地将多个期货Future[Future[Result]]展平为一个可以AsyncResult的单一期货。