Akka Java 在这里。我刚刚阅读了the “ask” pattern using futures上的Akka文档,并且我不了解几个方面的工作原理,当两个主管策略(决策者)和故障回调都是图片的一部分时。
假设我有两个演员Fizz
和Buzz
,其中Fizz
是Buzz
的父/创作者。由于Fizz
是Buzz
的父级,因此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
询问一些数据。发生这种情况时,可能会有以下三种结果之一:
Buzz
成功返回,并为Buzz
提供GetBuzzDataCallback
;或bData
抛出Buzz
;或BuzzIsAngryException
引发了其他一些异常/错误我想知道后两种情况会发生什么:
Buzz
是否将异常作为其GetBuzzDataCallback
参数发送了?或者,Throwable failure
是否被调用?或两者(如果两者回调和决策者/监督者策略都传递错误,那似乎有点多余并且复杂化?)与上述相同的情况,除了现在FizzFailureDecider
不 Fizz
的父/创建者。在这种情况下,我可以假设Buzz
被发送异常(作为其GetBuzzDataCallback
参数)吗?
我想我的问题的根源是这样的:当涉及未来回调的主管策略和时,谁会在抛出子异常时收到通知,以什么顺序通知?正如我上面提到的,对我来说,如果两者都收到失败/异常会更加混乱,因为那时你可能有一个主管策略试图重新启动Throwable failure
而回调试图做其他事情(可能是冲突的)例外。
请注意:虽然肯定不是必需的,但如果提供的任何代码段都是用Java而不是 Scala(Scala看起来像我的象形文字),我将不胜感激!
答案 0 :(得分:0)
什么问题基本上是启动一个临时演员,它将成为消息的发送者,这样当收件人回复时,它将最终进入这个临时演员。临时演员创建Promise
并将Future
赠送给调用者。如果答复在给定超时之前到达,则临时演员将使用成功结果完成Promise
。
监督总是发生在演员身上,而且由于问问是使用演员实现的,因此与其他演员发送可能使监督工作方式不同的消息相比,交互没有任何不同。
在您的情况下,异常将冒泡到父actor,以便它可以监督孩子。然后,除非您以某种方式发送由此失败触发的回复消息,否则超时将会发生,并且临时ask
- actor将使AskTimeoutException
失败。
因此,由于这种失败会通过两种方式传达给父母,因此在父母与子女之间的交流中使用问答模式通常不是一个好主意。