我正在尝试在我的 Scala 项目的演员系统中实现容错,以识别错误并处理它们。我正在使用经典演员。每个主管 Actor 有 5 个子 Actor,如果其中一个子 Actor 失败,我想重新启动该 Actor,并记录错误,正如我所提到的,处理导致该 Actor 失败的问题。
我One-For-One SupervisorStrategy
在我的主管演员类中实现了一个:
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 5, withinTimeRange = 1.minute) {
case e: ArithmeticException =>
logger.error(s"Supervisor: $e from $sender; Restarting!")
Restart
case e: NullPointerException =>
logger.error(s"Supervisor: $e from $sender; Restarting!")
Restart
case e: IllegalArgumentException =>
logger.error(s"Supervisor: $e from $sender; Restarting!")
Restart
case _: Exception =>
logger.error(s"Supervisor: Unknown exception from $sender; Escalating!")
Restart
}
我添加了throw new NullPointerException
一个我知道在每个参与者中调用的方法之一,因为系统从不/很少失败。但是,在log
文件中,我没有得到我所期望的,而是以下内容:
13:41:19.893 [ClusterSystem-akka.actor.default-dispatcher-21] ERROR akka.actor.OneForOneStrategy - null
java.lang.NullPointerException: null
我已经查看了很多示例,以及 Akka 文档中关于类型和经典角色的容错性,但我无法让它发挥作用。
编辑
在做了更多的研究之后,我发现我得到的错误的潜在原因可能是由子actor中的无限循环引起的,它抛出错误、重新启动、抛出错误等。
所以我采取了一种不同的方法,在主管actor中,我添加了一个变量sentError = false
,然后在一个告诉子actor开始工作的主管方法中,我添加了以下内容:
if(!errorSent){
errorSent = true
actor ! new NullPointerException
}
当一个子actor收到错误时,他们会抛出它。我采用了这种方法,这样这种情况只会发生一次,以避免循环。但是,不幸的是这并没有改变输出,我仍然得到上面提到的错误。