2017-06-30 13 views
1

scalaz.concurrent.Task私は2つの異なるサーバーにHTTP要求を実行しています。Scalaz task firstCompletedOf

私はFuture.firstCompletedOfと同様の方法でそれらを合成したいと思っています。それは、これらを両方ともパラレルで実行し、正常に完了した最初の結果を得ることです。

残念ながら、Task.gatherUnorderedは結果を返す前にすべてのタスクを完了するまで実行しているので、私がしたいことはありません。

答えて

1

ないネイティブscalaz.concurrentでそれを行う方法がわからが、これは私の作品:fs2

import scalaz.Nondeterminism._ 
import scalaz.std.either.eitherInstance 
import scalaz.syntax.bitraverse._ 

def race[A, B](t1: Task[A], t2: Task[B]): Task[A \/ B] = { 
    Nondeterminism[Task].choose(t1, t2).map { 
     _.bimap(_._1, _._2) 
    } 
} 

からscalaz.concurrentの後継 - bimapを使用することは確かに正しいですが、それはfs2.async#race

1

で、あります代わりの実装:

import scalaz.concurrent.Task 
import scalaz.Nondeterminism 

def firstOf[A, B, C](ta: Task[A], tb: Task[B])(fa: A => C, fb: B => C): Task[C] = 
    Nondeterminism[Task].chooseAny(ta.map(fa), Seq(tb.map(fb))).map(_._1) 

val task1 = Task { Thread.sleep(10000); 4 } 
val task2 = Task { Thread.sleep(5000); "test" } 
firstOf(task1, task2)(_.toString, identity).unsafePerformSync // test 

ここで私は非決定性正確な計算時間が分からない同等の値を得るために結果の静的検索が使用される。そのため、この関数は、同時実行された変換fafbを共通タイプに組み込みます。変換時間を計算するのが難しい場合は、変換後の最初の結果(たとえば、HTTPの場合は要求データの抽出など)を選択します。より単純な場合には、firstOfから次のようにrace関数の変形を検索します。