Akka Java 在这里 . 我刚刚阅读了the “ask” pattern using futures上的Akka文档,并且我不了解几个方面的工作原理,这些情况与主管策略(决策者)和故障回调都是图片的一部分有关 .
父母问孩子
假设我有两个演员, Fizz
和 Buzz
,其中 Fizz
是 Buzz
的父/创作者 . 因为 Fizz
是 Buzz
的父级,所以 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
成功返回并提供GetBuzzDataCallback
与bData
;要么 -
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 回答
问题是基本上启动一个临时演员,它将成为消息的发送者,这样当收件人回复时,它将最终进入这个临时演员 . 临时actor创建一个
Promise
并将Future
给它给调用者 . 如果答复在给定超时之前到达,则临时演员将使用成功结果完成Promise
.监督总是发生在演员身上,并且由于问题是使用演员实现的,因此与其他演员发送可能使监督工作方式不同的消息相比,交互没有任何不同 .
在您的情况下,异常将冒泡到父actor,以便它可以监督孩子 . 然后,除非你以某种方式发送由此失败触发的回复消息,否则超时将会发生,临时
ask
-actor将在AskTimeoutException
失败 .因此,由于这种失败将通过两种方式传达给父母,因此在父母与子女之间的沟通中使用问答模式通常不是一个好主意 .