0

我正在尝试在我的 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收到错误时,他们会抛出它。我采用了这种方法,这样这种情况只会发生一次,以避免循环。但是,不幸的是这并没有改变输出,我仍然得到上面提到的错误。

4

0 回答 0