いくつかの先物を連鎖させるためのエレガントな解決策を見つけるのに苦労しています。実装しようとしているメソッドは次のようになります (キャッシュの一部です)。
def acquire(key: A, producer: => Future[B]): Future[B]
そして、アルゴリズムはおおよそ次のとおりです。
- キーがロックされている場合は、実行時例外を通じてすぐに (Future.failed を使用することの進歩はありますか?)
future { getOrRefresh }それ以外の場合は、キーを取得するのに時間がかかるため、ブロックを開きますgetOrRefreshどちらかがストレートを返し、Bそれが先物とメソッドの結果です- またはそれを実行する必要があります
producer
最後のステップは、未来の中から未来を「平坦化」する必要があることを意味します。つまり、 はできないので、outer.flatMapを使うのが戦略だと思いますAwait。
現在、メソッドを使用して を取得するか、 を使用して巻き戻したをAwait取得できるという点で、奇妙な統合失調症があります。問題は、 の場合、外側の未来を完了する前にロックを解除する必要があるため、 に固執する必要があるということです。Option[Try[B]]readyBresultFailureAwait.ready
これは醜くなります:
val fut = producer
val prod = Await.ready(fut, Duration.Inf).value.get
if (prod.isFailure) sync.synchronized { locked = false }
prod.get
これはそんなに醜いことができますか?これを行うためのより良い方法があるはずです。
繰り返しになりますが、Future[B]実行中から、 で完了するいくつかのピア Future を実行しB、ピアの結果を返しますが、失敗した場合は、メインの Future を完了する前にロックをクリーンアップします。