3

結果を返すのに時間がかかるデータベースに対して 2 つの呼び出しを行いたいのですが、現在のスレッドをブロックしたくありません。データベース呼び出しをラップするために Akka Futures を使用しました。

両方の呼び出しが戻るのを待つ (ブロックする) 代わりに、呼び出されるコールバック関数を指定して、応答をレンダリングできるようにしたいと考えています。それ、どうやったら出来るの?これが私のコントローラーコードです:

def showPie = IsAuthenticated(Roles.validator) { user => implicit request =>
    val eventUid = request.session.get(EventUid).get

    val printed = Akka.future(TicketRepository.getCountForState(eventUid, "Printed"))
    val validated = Akka.future(TicketRepository.getCountForState(eventUid, "Validated"))

    //this would be evil, because it would block: Ok(views.html.pie(printed.await(1000).get, validated.await(1000).get)) 

    //create a promise for all the promised results
    val promise = Promise.sequence(List(printed, validated))

    //this doesnt work, but how can I make it work WITHOUT blocking this thread?
    promise.callWhenResultIsReady(Ok(view.html.pie(promise.get))
}
4

1 に答える 1

6

あなたは近くにいます。mapそれを処理する約束を簡単に呼び出すことができます。Async ブロック内では、ノンブロッキングのままです。関連ドキュメント(「AsyncResult」を参照)。

def showPie = IsAuthenticated(Roles.validator) { user => implicit request =>
    val eventUid = request.session.get(EventUid).get

    val printed = Akka.future(TicketRepository.getCountForState(eventUid, "Printed"))
    val validated = Akka.future(TicketRepository.getCountForState(eventUid, "Validated"))

    //create a promise for all the promised results
    val promise = Promise.sequence(List(printed, validated))
    Async {
        promise map { res =>
            Ok("Got it!" + res)
        }
    }
}

edit : 以下のコメントから、Async ブロックを詳しく見てみましょう。Asyncを受け取り、(必要なもののサブタイプである をPromise返します。AsyncResultResultAction

    Async {
        // We take the promise, and add something akin to a callback
        //  function with `map`. This new function is called when `promise`
        //  is complete.
        val result = promise map { res => // this is the redeemed promise
          Ok("Got it!" + res)
        }
        result // this is the new promise
    } 

mapが完了すると関数が呼び出されるためpromise、これはノンブロッキングのままです。このブロック全体がAsyncResult, と Play! ですぐに戻ります。終了時にクライアントに戻ることで、同様の方法でそれを管理します (その間、Play! は他のことをするために解放されます)。

于 2012-09-25T14:41:12.220 に答える