我目前有代码使用Ask Pattern调度请求。调度的请求将生成一个Akka Actor,它发送HTTP请求然后返回响应。我正在使用Akka的断路器API来管理我调用的上游Web服务的问题。
如果断路器处于打开状态,则所有后续请求都会快速失败,这是所需的效果。但是当actor快速失败时它只会抛出一个CircuitBreakerOpenException,停止actor,但是在生成AskTimeoutException之前,控件不会返回发出初始请求的代码。
这是调度请求的代码
Timeout timeout = new Timeout(Duration.create(10, SECONDS));
Future<Object> future = Patterns.ask(myActor, argMessage, timeout);
Response res = (Response ) Await.result(future, timeout.duration());
这是断路器
getSender().tell(breaker.callWithSyncCircuitBreaker(new Callable<Obj>()
{
@Override
public Obj call() throws Exception {
return fetch(message);
}
}), getSelf()
);
getContext().stop(getSelf());
当执行此代码块并且电路打开时,它会快速抛出异常但是我想将控制权返回给处理未来的代码,而不必等待超时。
这可能吗?
答案 0 :(得分:3)
当演员失败并重新启动时,如果它正在处理消息,则不会自动向该发件人发送任何响应。如果您希望向该发件人发送有关该特定故障的消息,请明确捕获该异常,并以失败的结果回复该发件人,确保在您进入任何未来的回调之前先捕获发件人,以避免关闭此可变状态。您也可以尝试在preRestart中执行此操作,但这并不是非常安全,因为如果您在演员中使用期货,发件人可能已经更改了。