【问题标题】:How Akka Futures and Supervisor Strategies deal with failureAkka Futures 和 Supervisor Strategies 如何处理失败
【发布时间】:2015-08-24 16:50:29
【问题描述】:

Akka Java 在这里。我刚刚阅读了 the “ask” pattern using futures 上的 Akka 文档,我不了解一些事情是如何工作的,关于 主管策略(决策者)和失败回调都是图片一部分的场景。

家长问孩子

假设我有两个演员,FizzBuzz,其中FizzBuzz 的父/创建者。因为FizzBuzz 的父级,所以它有一个SupervisorStrategy 用于处理其故障的Buzz

// Groovy pseudo-code
class Fizz extends UntypedActor {
    ActorRef buzz

    // Contstructor omitted for brevity, but Buzz is the child of
    // Fizz.

    @Override
    void onReceive(Object message) {
        if(message instanceof FizzRequest) {
            FizzRequest fReq = message as FizzRequest

            // Exceptions thrown here (inside of Buzz) will be
            // handled by Fizz’s supervisor strategy.
            Future<BuzzData> bDataFut = Patterns.ask(buzz,
                fReq.buzzRequest, 500)
            bDataFut.onComplete(new GetBuzzDataCallback())

            // etc.
        } else {
            unhandled(message)
        }
    }

    @Override
    SupervisorStrategy supervisorStrategy() {
        new FizzSupervisorStrategy()
    }
}

class Buzz extends UntypedActor {
    // …etc.
}

class FizzDecider extends Function<Throwable,Directive> {
    @Override
    Directive apply(Throwable throwable) {
        if(throwable instanceof BuzzIsAngryException) {
            return SupervisorStrategy.restart()
        }

        SupervisorStrategy.stop()
    }
}

class FizzSupervisorStrategy extends OneForOneStrategy {
    FizzSupervisorStrategy() {
        super(true, new FizzDecider())
    }
}

class GetBuzzDataCallback extends OnComplete<BuzzData> {
    @Override
    void onComplete(Throwable failure, BuzzData bData) {
        if(failure != null) {
            // If Buzz is the child of Fizz, does this code execute, or
            // just the FizzDecider above? Or both? I’m so confused!
        } else {
            // Handle success. Likely use an ‘Inbox’ to send
            // ‘bData’ back to Fizz.
        }
    }
}

有时,Fizz 需要向Buzz 询问一些数据。发生这种情况时,可能会出现以下三种结果之一:

  1. Buzz 成功返回并为GetBuzzDataCallback 提供bData;或
  2. Buzz 抛出 BuzzIsAngryException;或
  3. Buzz 引发其他类型的异常/错误

我想知道后两种情况会发生什么:

  • 谁会收到异常通知,以什么顺序以及如何通知?换句话说,GetBuzzDataCallback 是否将异常作为其Throwable failure 参数发送?或者,是否调用了FizzFailureDecider?或者两者都有(如果 回调和决策者/主管策略都通过了错误,这似乎有点多余和复杂)?

家长问非孩子

与上述情况相同,除了现在Fizz 不是 Buzz 的父/创建者。在这种情况下,我可以假设GetBuzzDataCallback 发送了异常(作为其Throwable failure 参数)吗?

我想我的问题的根源是:当涉及主管策略未来回调时,当抛出子异常时通知谁,以及以什么顺序?正如我上面提到的,对我来说,如果两者都收到失败/异常,那将更加令人困惑,因为那时你可能有一个主管策略试图重新启动 Buzz 而回调正试图做其他事情(可能是冲突的)例外.

请注意:虽然肯定不是必需的,但如果提供的任何代码 sn-ps 是 Java 和 不是 Scala(Scala 看起来像象形文字我)!

【问题讨论】:

  • 为什么反对票没有解释(我称之为打了就跑)?!?这个问题显示研究,不是骗子,是SSCCE。放开我,你这个恶魔!
  • 您的链接指向您提出的另一个问题,而不是 Akka 文档。 (注意我没有给你投反对票)

标签: java exception callback akka akka-supervision


【解决方案1】:

ask 所做的基本上是启动一个临时 Actor,它将成为消息的发送者,这样当接收者回复时,它就会在这个临时 Actor 中结束。临时演员创建一个Promise 并将Future 送给调用者。如果回复在给定超时之前到达,则临时参与者会以成功的结果完成Promise

监督总是发生在 Actor 中,由于 ask 是使用 Actor 实现的,因此与随机其他 Actor 向其发送可能使监督工作不同的消息相比,交互没有任何不同。

在您的情况下,父actor会出现异常,以便它可以监督子actor。然后,除非您以某种方式发送由该故障触发的回复消息,否则超时将会命中,并且临时的 ask-actor 将在未来失败并返回 AskTimeoutException

因此,由于此故障会通过两种方式到达父级,因此在父子间通信中使用 ask 模式通常可能不是一个好主意。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    相关资源
    最近更新 更多