0

以下を考えると:

import akka.dispatch.{FutureTimeoutException, Future}

val f1 = Future({ Thread.sleep(2000); 0}, 500)

f1.onException {
  case timeout: FutureTimeoutException => -1
}

f1.recover {
    case timeout: FutureTimeoutException => -2
}

println(f1.get)

それでも例外が発生するのはなぜですか? 代わりに実際の値が返されるようにタイムアウトから回復する方法はありますか?

4

2 に答える 2

1

ビクターが言ったことに基づいて、特定のタイプの障害からをFuture使用して回復したい場合は、それが新しいを返すrecoverことに注意する必要があり、回復機能を得るためにそれを呼び出す必要があります。このようなもの:recoverFutureget

val f1 = Future({ Thread.sleep(2000); 0}, 500)
val withRecover = f1.recover {
  case timeout: FutureTimeoutException => -2
}
println(withRecover.get)

Futureまたは、次のように作成にチェーンすることもできます。

val f1 = Future({ Thread.sleep(2000); 0}, 500).recover {
  case timeout: FutureTimeoutException => -2
}
println(f1.get)

編集

したがって、scala 2.10 の Future と Promises と比較して、Akka 1.3 では独自の内部 Future で動作が異なるようです。Akka 1.3 では、リカバリはタイムアウト以外の状況でのみ機能します。それを回避する方法の例を紹介しましたが、最新の scala と akka を利用するには、可能であればアップグレードする必要があります。

import akka.dispatch._
import java.util.concurrent.TimeUnit.{ NANOSECONDS ⇒ NANOS, MILLISECONDS ⇒ MILLIS }
import akka.actor.Actor

object FutureTest {
    def main(args: Array[String]) {
        val f1: Future[Int] = Future({
            Thread.sleep(2000)
            0
        }, 500)

        val f2 = recoverTO(f1) {            
            -2
        }

        println(f2.get)
    }

  def recoverTO[T, A >: T](fut:Future[T])(f: => A): Future[A] = {
    val fa = new DefaultCompletableFuture[A](fut.timeoutInNanos, NANOS)
    fut.onTimeout { future =>
      fa completeWithResult f
    }
    fut.onComplete {
      fa complete _.value.get
    }    
    fa
  }    
}
于 2013-07-21T18:03:07.573 に答える
0

Future は 1 回だけ書き込み可能であるため、値 (または例外) を持つ Future を変更する唯一の方法は、新しいFuture を返すことです。「recover」のリターンタイプを確認してください。

于 2013-07-21T15:55:21.820 に答える