私はFuture[Option[Elephant]]
を返して、ネットワーク上でElephant
を探す関数を持っています。戻り値はFuture
なので、ネットワークコールが非同期に発生している間に関数がすぐに戻ることができます。Scalaでのテール再帰的な機能的ポーリング
def checkForElephant : Future[Option[Elephant]] = ???
は、私は何をしたいことはpollForElephant
と呼ばれる関数を記述です:Some
は象が発見されたことを意味している間は、None
はまだ利用できませんを意味しているためOption
が含まれています。
def pollForElephant : Future[Elephant] = ???
この機能さえあった場合、Elephant
が発見されるまでcheckForElephant
を呼び出し、すぐに成功する要素が最初のチェックで発見された場合、それ以降は再び10秒ごとにチェックしますプロセス上Future
を返す必要がありますゾウはいないし、永遠に試してみる必要があります。
これを行う簡単な方法は、単にポーリングして、全体の不倫上Future
を作成するためにFuture
ドメイン外の再帰関数を記述し、同期するチェックを強制することです:
import scala.annotation.tailrec
import scala.concurrent.{Await,Future,blocking}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
class Elephant;
def checkForElephant : Future[Option[Elephant]] = ???
def synchronousCheckForElephant : Option[Elephant] = blocking {
Await.result(checkForElephant, Duration.Inf)
}
@tailrec
def poll(last : Option[Elephant]) : Elephant = {
last match {
case Some(elephant) => elephant
case None => {
blocking {
Thread.sleep(10.seconds.toMillis)
}
poll(synchronousCheckForElephant)
}
}
}
def pollForElephant : Future[Elephant] = Future {
poll(synchronousCheckForElephant)
}
このドメインがFuture
から始まり、強制的に同期させてから元に戻って、ひどく控えめなようです。私はFuture
からすべてを行うことができるはずだと思った。だから、私はこれを試してみました:上記のコメントが言うよう
import scala.annotation.tailrec
import scala.concurrent.{Await,Future,blocking}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
class Elephant;
def checkForElephant : Future[Option[Elephant]] = ???
// oops! this is not @tailrec
def poll(last : Future[Option[Elephant]]) : Future[Elephant] = {
last.flatMap { mbElephant =>
mbElephant match {
case Some(elephant) => Future.successful(elephant)
case None => {
blocking {
Thread.sleep(10.seconds.toMillis)
}
poll(checkForElephant)
}
}
}
}
def pollForElephant : Future[Elephant] = poll(checkForElephant)
、poll(...)
関数は末尾再帰的ではありません。象は到着するまでに時間がかかるかもしれませんが、私は無期限に待つことになっていますが、スタックが壊れる可能性があります。
そして、全体がちょっと変わっています。私はちょうど理由が簡単な同期アプローチに戻すべきですか? Future
に滞在している間に私が意味することをする安全な方法はありますか?
参照:https://stackoverflow.com/questions/16973838/how-do- i-make-a-function-with-future-tail-recursive – PH88
@ PH88ありがとうございました。それは有益で面白いです。私はそれについて少し考えなければならない。 –