2

私は初めて Play 2 で開発しているので、コントローラーでこのようなことを頻繁に行っていることがわかりました (より単純な例の 1 つです)。

 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"))}
  )

一方で、コントローラーへの多くの先物/リターンがオーバーヘッドを追加する可能性があると考えています。一方、1 つの先物への呼び出しはより読みやすくなりますが、Akka システムで実行されるより大きな「スレッド」につながります。はるかに大規模なジョブの場合、私は追加の Akka システムを持っているので、これらはおそらく最大 4 つの SQL トランザクションしか包含しません。私がApacheベンチから解決できる限り、上記の例の間に違いはありません..不足しているものはありますか?

4

1 に答える 1

3

例は同等であるため、パフォーマンスに違いはありません。

あなたが書くとき:

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

その評価は開始されずFuture、マップされたときにのみ実行されます。

私が理解しているように、先物構成について考える必要があります。これは私がお勧めする本当に素晴らしいドキュメントです: http://docs.scala-lang.org/sips/pending/futures-promises.html

あなたの質問に答えるために、一連のクエリを順番に実行する必要がある場合、DBアクセスごとに1つずつ、複数のFutureを持っていても違いはないと思います。たとえば、レコードを取得してから削除します。

Future を利用できるのは (アプリをノンブロッキングにする以外に)、for-comprehension 構文を利用して、2 つ以上の非同期 Future を同時に実行できるようにすることです。

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

また、複数のブロックflatMapを持つよりも、一緒に Future を構成するために使用することをお勧めします。Async{}このようにして、複数の Future を効果的にフラット化Future[Future[Result]]して、単一の Future にすることができますAsyncResult

于 2012-12-11T23:59:55.040 に答える