Akka - 如何处理终止

时间:2014-04-22 12:47:09

标签: scala akka

我在我的akka​​应用程序中使用redis-react-nb库。不幸的是,当与redis的连接丢失时,库将以context stop self

停止

这意味着我的应用程序会收到如下的终止通知:

def receive: Actor.Receive = {
          case Terminated(actorRef) =>
            ...
        }

所以我想知道该怎么做。理想情况下,我想重新启动所有子actor,以便使用新的redis连接初始化它们 - 基本上将actor系统重置为其初始状态。

我是否在概念上遗漏了什么?或者有没有办法让演员重新启动所有的孩子而不会收到例外? self ! RestartAll或类似的东西?

2 个答案:

答案 0 :(得分:2)

另一种看待这种情况的方法是说你正在谈论的演员取决于redis演员,没有它就无法继续工作。在这种情况下,将其作为对其父级的失败进行升级并让其重新启动是合适的。如果您不处理Terminated消息,那么将抛出DeathPactException,但您必须在父服务器中安装适当的supervisorStrategy,因为该服务器的默认值是终止子服务器。我建议您在收到Terminated消息时定义并抛出RedisFailedException。

答案 1 :(得分:0)

其中一个可能的解决方案是查看SupervisorStrategy.Restart的实施情况。不幸的是,该实现使用InternalActorRef

  final def restartChild(child: ActorRef, cause: Throwable, suspendFirst: Boolean): Unit = {
    val c = child.asInstanceOf[InternalActorRef]
    if (suspendFirst) c.suspend()
    c.restart(cause)
  }

所以我假设没有内置解决方案,您应该自己动手。

  def receive = {
    case Terminated(actorRef) => self ! RestartAll
    case RestartAll =>
      context.children.foreach(_ ! PoisonPill)
      //start all necessary actors again
  }