2017-01-26 10 views
2

私たちはScala Play webappを持っています。これはHTTPリクエストの一部としてデータベース操作を行い、それぞれは未来です。通常、Futuresを非同期コントローラアクションにバブルアップし、Playがそれらを待っているようにします。実行を保証するために、すべての先物を待つ必要がありますか?

私は未来を泡立てていないか、それが完了するのを待っていない場所にも気づいています。私はこれが悪いと思うのは、HTTPリクエストが失敗しても失敗するということです。実際には未来が実行されることさえ保証されますか? HTTPリクエストが提供された後、待っていた未来のプレイがドロップされるのか、バックグラウンドで実行され続けるのでしょうか?

答えて

2

TL; DR

  1. プレイは、HTTPレスポンスを送信した後、あなたのFuture秒を殺すことはありません。
  2. Futureのいずれかが失敗した場合、エラーは報告されません。

ロングバージョン

HTTPレスポンスが送信されたとき、あなたの先物が殺されることはありません。あなたが先物のいずれかが失敗した場合、要求は失敗しないことが正しいしかし

def futuresTest = Action.async { request => 

    println(s"Entered futuresTest at ${LocalDateTime.now}") 

    val ignoredFuture = Future{ 
     var i = 0 
     while (i < 10) { 
     Thread.sleep(1000) 
     println(LocalDateTime.now) 
     i += 1 
     } 
    } 

    println(s"Leaving futuresTest at ${LocalDateTime.now}") 

    Future.successful(Ok) 
    } 

:あなたはこのように自分自身のためにそれを試してみることができます。これが問題であれば、またはのflatMapsのためにを使用して先物を構成することができます。ここで何ができるかの例は、(私はあなたの未来は、あなたの未来はparalellに実行させるために側efects(Future[Unit]

を実行することを仮定しています

val dbFut1 = dbCall1(...) 
val dbFut2 = dbCall2(...) 
val wsFut1 = wsCall1(...) 
val fut = for(
    _ <- dbFut1; 
    _ <- dbFut2; 
    _ <- wsFut1 
) yield() 

fut.map(_ => Ok) 

は、彼らが順番に実行させる

val fut = for(
    _ <- dbCall1(...); 
    _ <- dbCall2(...); 
    _ <- wsCall2(...) 
) yield() 

fut.map(_ => Ok) 
1

何もそれの結果を待つとしていないので、それは実際にも、ドロップ を再生するのでしょうか? 、未来はまったく実行されることを保証んHTTPリクエストが待たれていた未来の未来は、 をバックグラウンドで実行していますか?

この質問は実際にプレイよりもはるかに深い実行されます。 「私が未来を同期的に待たなければ、GCedなしで実際に完了することをどうすれば保証できますか?」これに答えるには、GCがスレッドを実際にどのように表示するかを理解する必要があります。 GCの観点から、スレッドは「ルート」と呼ばれています。そのようなルートは、ヒープがそのオブジェクトを横断してどのオブジェクトがコレクションに適格であるかを見るための開始点です。根の中には、例えばアプリケーションの生存期間を通じて生存することが知られている静的なフィールドもあります。

だから、あなたがそのようにそれを表示したとき、およびFutureは、実際に我々がExecutionContextと呼ぶ基礎となるExecutorService(経由で利用可能なスレッドのプールから専用スレッド上で動作する機能をキューイングしている、何をするかを考えますScalaで)、完了を待っていなくても、JVMランタイムはFutureが完了するまで実行することを保証します。ファンクションをラップするオブジェクトFutureについては、未完了のファンクションボディへの参照を保持するので、Future自体は収集されません。あなたはその観点から考えると

Futureの実行は非同期で起こるので、それは、完全に論理的だし、我々は通常、など

継続など mapflatMaponCompleteを使用して、非同期にそれを処理し続けます
関連する問題