Akka Futures和Supervisor Strategies如何应对失败

时间:2015-08-24 16:50:30

标签: java exception-handling callback akka supervisor

Akka Java 在这里。我刚刚阅读了the “ask” pattern using futures上的Akka文档,并且我不了解几个方面的工作原理,当两个主管策略(决策者)和故障回调都是图片的一部分时。

父母问孩子

假设我有两个演员FizzBuzz,其中FizzBuzz的父/创作者。由于FizzBuzz的父级,因此SupervisorStrategy的{​​{1}}可以处理其失败:

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

  1. Buzz成功返回,并为Buzz提供GetBuzzDataCallback;或
  2. bData抛出Buzz;或
  3. BuzzIsAngryException引发了其他一些异常/错误
  4. 我想知道后两种情况会发生什么:

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

    家长询问非孩子

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

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

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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