【问题标题】:Sending back to sender, from supervisor, in case of failure在失败的情况下从主管发送回发件人
【发布时间】:2016-03-13 09:17:51
【问题描述】:

我有一个 Actor,它充当主管,但还需要向调用者“返回”数据,这是否是一个 Actor 无关紧要。

我在问我的主管,我们称他为 SV。

SV 处理我发送给他的消息,并返回一个响应。

val system = ActorSystem("ActorSystem")
val sv = system.actorOf(Props[SV], name = "SV")

sv ? msg

而SV的recieve方法是这样的:

def receive = {
    case msg => (someChild ? msg).pipeTo(sender)
    ...
}

这一切都很好。 问题是当孩子抛出异常时,这个异常会被主管策略捕获。

override def supervisorStrategy = OneForOneStrategy () {
    case e : Throwable => {
        val newResponse = someNewResponse
        sender ! newResponse
        ...
    }
}

sender 不再是指最初调用 SV 的人,而且我似乎无法弄清楚如何将消息发送回被询问者,并回到我原来的流程。

【问题讨论】:

    标签: scala akka akka-supervision


    【解决方案1】:

    您是否使用主管策略和异常来控制流程或您的数据?考虑使用类型系统(Option 类型或响应 Failure 上的 Failure)处理您的子 Actor 中的“异常”情况,并毫无例外地处理响应流。

    主管策略是针对未处理的异常。 当发生未处理的异常时,您将失去向发件人回复消息的能力。除非您像 Roland Kuhn 建议的那样将发件人包装在未处理的异常中。

    让主管策略来处理 Actor 系统应如何响应您未处理的异常,方法是将它们映射到 Directive

    【讨论】:

      【解决方案2】:

      三个 Actor 规则之一是:“一个 Actor 可以向它认识的其他 Actor 发送有限数量的消息。”最后两个词在这里很关键:如果没有以某种方式将监督者介绍给原始发送者,并且失败(异常)本身也不包含发送者的引用,那么监督者不可能向发送者发送消息。要么捕获子actor中的所有异常,将它们与发送者一起包装成你自己的异常类型,然后重新抛出,要么原始消息需要通过主管传送到子actor并返回,以便主管可以看到回复发生故障时突出显示。

      【讨论】:

      • 我不确定我是否理解,“原始消息需要通过主管传递给孩子并返回”,这不是我在ask孩子时所做的事情,来自主管?它永远不会直接返回到我询问的位置,因为发生了异常,所以 SupervisorStrategy 被击中。从这里我现在想向原始发件人(来自主管)发送一条消息,并给出不同的响应,如果我的问题仍然不够清楚,我可以根据需要用流程图更新它。
      • 啊,对,我没有正确解析ask的用法;是的,这就是我的意思。那么在制定supervisorStrategy的时候还需要在supervisor中捕获原来的sender,也就是管理未完成请求的数量(以免混淆)。
      猜你喜欢
      • 1970-01-01
      • 2013-07-26
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 2013-03-01
      • 1970-01-01
      • 2016-10-31
      相关资源
      最近更新 更多