首页 文章

Akka Futures和Supervisor Strategies如何应对失败

提问于
浏览
0

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 的某些数据 . 发生这种情况时,可能会有以下三种结果之一:

  • Buzz 成功返回并提供 GetBuzzDataCallbackbData ;要么

  • Buzz 抛出 BuzzIsAngryException ;要么

  • Buzz 抛出了其他一些异常/错误

I’m wondering what happens with the latter two cases:

  • 谁被告知异常,以什么顺序,以及如何?换句话说,是 GetBuzzDataCallback 将异常作为 Throwable failure 参数发送了吗?或者, FizzFailureDecider 是否被调用?或者两者(如果回调和决策者/监督者策略都传递了错误,那似乎有点多余并且复杂化)?

家长要求非孩子

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

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

Please note :虽然肯定不是必需的,但如果提供的任何代码片段都是Java而不是Scala(Scala看起来像我的象形文字),我将不胜感激!

1 回答

  • 0

    问题是基本上启动一个临时演员,它将成为消息的发送者,这样当收件人回复时,它将最终进入这个临时演员 . 临时actor创建一个 Promise 并将 Future 给它给调用者 . 如果答复在给定超时之前到达,则临时演员将使用成功结果完成 Promise .

    监督总是发生在演员身上,并且由于问题是使用演员实现的,因此与其他演员发送可能使监督工作方式不同的消息相比,交互没有任何不同 .

    在您的情况下,异常将冒泡到父actor,以便它可以监督孩子 . 然后,除非你以某种方式发送由此失败触发的回复消息,否则超时将会发生,临时 ask -actor将在 AskTimeoutException 失败 .

    因此,由于这种失败将通过两种方式传达给父母,因此在父母与子女之间的沟通中使用问答模式通常不是一个好主意 .

相关问题