6

当未来的演员抛出异常时会发生什么?

根据http://doc.akka.io/docs/akka/snapshot/scala/futures.html上的 Akka 文档:

Actor 或调度程序是否正在完成 Future 无关紧要,如果捕获到异常,Future 将包含它而不是有效结果。如果 Future 确实包含异常,调用 Await.result 将导致它再次被抛出,以便正确处理。

我不确定这是我在运行这段代码时看到的:

  class Worker extends Actor {
    def receive = {
      case i: Int => throw new RuntimeException
    }         
  }

  implicit val system = ActorSystem("MySystem")
  val worker = system.actorOf(Props(new Worker), name="worker")
  implicit val timeout = Timeout(5 minutes)
  val future = worker ? 0
  val res = Await.result(future, 10 seconds)

根据文档, Await.result 应该再次抛出异常,但我得到的是 TimeoutException!有人可以澄清一下吗?

4

1 回答 1

15

对于参与者,您需要捕获异常并将其作为失败状态返回。现在你没有向发件人返回任何东西,所以你得到一个超时异常:

class Worker extends Actor {
  def receive = {
    case i: Int => {
      try {
        throw new RuntimeException
        sender ! "Some good result"
      } catch {
        case e: Exception =>
          sender ! akka.actor.Status.Failure(e) // Alert the sender of the failure
          throw e // Alert any supervisor actor of the failure
      }
    }
  }
}

Futures 可以更优雅地处理这个问题,因为它们总是发送结果,而 Actor 不发送(这会给你与上面相同的结果):

  val future = Future {
    throw new RuntimeException
  }
于 2013-04-19T02:40:01.807 回答