监督.Restart和Supervision.Resume之间的区别是什么?

时间:2016-10-02 23:04:59

标签: scala akka akka-stream

Supervision.RestartSupervision.Resume之间的区别是什么?

情况如下。我有3个来自Source(List(1, 2, 3))的元素。在runForeach中,如果元素为2,则抛出异常。对于Supervision.Restart,我预计只会处理1。但奇怪的是,我看到3到达了下沉。为什么?我使用的是Akka 2.4.11

import akka.actor.{ActorRef, ActorSystem}
import akka.stream.{ActorMaterializer, ActorMaterializerSettings, OverflowStrategy, Supervision}
import akka.stream.scaladsl.Source

val decider: Supervision.Decider = {
  case _: NotImplementedError =>
    Supervision.Restart
  case _                      =>
    Supervision.Stop
}

implicit val system = ActorSystem("root")
implicit val executor = system.dispatcher
implicit val materializer = ActorMaterializer(ActorMaterializerSettings(system).withSupervisionStrategy(decider))(system)

Source(List(1, 2, 3))
  .map { v =>
    if (v == 2)
      throw new NotImplementedError
    v
  }
  .runForeach(println)

https://scalafiddle.io/sf/HSj01pO/3

1 个答案:

答案 0 :(得分:2)

在您的示例中,您的Flow是(也称为FlowShape):

.map { v =>
  if (v == 2)
    throw new NotImplementedError
  v
}

主要区别在于:

  • Supervision.Restart:将创建一个新的actor实例,它将具有您类的初始状态。之前的状态将会丢失。在您的情况下,它将是您Flow

  • 的状态
  • Supervision.Resume:同一个实例与之前的状态一起使用。在您的情况下,它将是您Flow

  • 的状态

在您的情况下,您的Flow是无国籍的,因此Supervision.RestartSupervision.Resume之间没有区别。

由于您有case _: NotImplementedError => Supervision.Restart,因此1获得map并且到达Sink2会引发NotImplementedError重新启动您的Flow,删除该邮件,但不会停止您的信息流。然后3得到map ped并到达Sink。因此,您应该在输出13中看到。