0

Akka Java在这里。我刚刚阅读了有关使用 futures 的“询问”模式的 Akka 文档,并且不了解一些事情是如何工作的,关于主管策略(决策者)和失败回调都是图片的一部分的场景。

家长问孩子

假设我有两个演员,Fizz并且的父/创建者Buzz在哪里。因为is的父级,它有一个for来处理它的失败:FizzBuzzFizzBuzzSupervisorStrategyBuzz

// 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成功返回并提供GetBuzzDataCallbackwith bData;或者
  2. Buzz抛出一个BuzzIsAngryException;或者
  3. Buzz引发其他类型的异常/错误

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

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

父母询问非儿童

与上面相同的场景,除了nowFizz不是. 在这种情况下,我可以假设发送异常(作为它的参数)吗?BuzzGetBuzzDataCallbackThrowable failure

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

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

4

1 回答 1

0

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

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

在您的情况下,异常将冒泡到父演员,以便它可以监督孩子。然后,除非您以某种方式发送由此故障触发的回复消息,否则超时将命中并且临时ask-actor 将在未来失败,并带有AskTimeoutException.

因此,由于这种失败会通过两种方式到达父母,因此在父母与孩子的沟通中使用询问模式通常可能不是一个好主意。

于 2015-09-05T11:20:08.880 回答