【问题标题】:Akka Actor Passing Actor References AroundAkka Actor 传递 Actor 引用
【发布时间】:2018-02-22 16:14:02
【问题描述】:

我有两个 Actor 实例,如下所示:

class MyActor1(actorRef2: Actor) extends Actor {
  ....
  ....
}

class MyActor2 extends Actor {
  ....
  ....
}

上述两个演员都是从我有一些监督的顶级演员创建的。

现在我的问题是,如果 MyActor2 以某种方式被杀死,我传递给 MyActor1 的这个 MyActor2 的引用会发生什么? MyActor1 是否仍可以使用传入的引用发送消息,以便复活后的 MyActor2 仍能收到消息?

【问题讨论】:

    标签: akka


    【解决方案1】:

    会发生什么取决于您所说的“杀死”以及MyActor2 的主管策略是什么。

    1. 如果通过stop方法停止对MyActor2的引用,例如context.stop(myActor2),那么:

      当前消息的处理,如果有的话,将在actor停止之前继续,但邮箱中的其他消息将不会被处理。默认情况下,这些消息会发送到 ActorSystem 的 deadLetters,但这取决于邮箱实现。

    2. 如果对MyActor2 的引用因PoisonPill 消息而停止,则:

      ...akka.actor.PoisonPill 消息...将在处理消息时停止 actor。 PoisonPill 作为普通邮件排队,将在邮箱中已经排队的邮件之后处理。

    3. 如果对MyActor2 的引用因Kill 消息而停止,则:

      PoisonPill 不同,这将导致actor 抛出一个[n] ActorKilledException,从而触发失败。 Actor 将暂停操作,并询问其主管如何处理故障,这可能意味着恢复 Actor、重新启动它或完全终止它。

    如果您用context.stopPoisonPill 停止myActor2,那么在该actor 停止后发送给该actor 的消息将变成死信。如果您发送myActor2Kill 消息,那么您为处理ActorKilledException 定义的任何主管策略都会启动。用于处理ActorKilledExceptiondefault supervisor strategy 是停止actor,如前所述,将导致actor停止后发送的所有消息进入死信邮箱。

    您可以通过更改主管策略以在出现ActorKilledException 时重新启动actor 来覆盖此默认行为。重启会保留ActorRef,并且对引用了actor的实体是透明的:在actor重启时发送给actor的消息将被正常处理。您还可以恢复演员,这基本上忽略了异常。

    【讨论】:

    • 好的,这意味着一旦我重新启动 MyActor2,我仍然可以继续处理从 MyActor1 发送的新消息!这就是我想要的!
    • 一个关键点是“重启(使用监督)”。如果你停止了这个actor,并且碰巧用相同的名字开始了一个新的on,那么之前的actor ref 将是无效的。如果您使用重启监督,红色仍然有效
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 2015-01-06
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    相关资源
    最近更新 更多