1
我有一场重要的角色需要拨打电话一个缓慢的一个场景(15 - 20 秒)远程系统:为阿卡演员舱壁策略
// Non-actor code equivalent
public Result makeSlowNetworkCall(Request request) {
Result result = slowServiceClient.soooooSlow(request); // Could be up to 15 - 20 SECONDS (mehhhh)
return result;
}
的阿卡相当于这是目前看起来像:
// Groovy
class SlowServiceActor extends UntypedActor {
@Override
void onReceive(Object message) {
if(message instanceof CallSlowService) {
Request request = (message as CallSlowService).request
Result result = makeSlowNetworkCall(request)
// ...now do something with result, some 15 seconds later
}
}
Result makeSlowNetworkCall(Request request) {
slowServiceClient.soooooSlow(request)
}
}
显然,这是阻止坏,坏,坏的。阅读this excellent article on handling non-blocking DB calls后,我的主要外卖的是,有两个基本“舱壁”战略,我可以使用:
- 将所有
SlowServiceActor
情况下,在自己的调度员,从其他演员隔离的延迟/阻塞岬/不直接与慢服务交互的线程;和 - 通过
Futures
真正调用缓慢的服务“异步”
所以我的最好的尝试迄今为止是:
// In application.conf:
slowServiceDispatcher {
...config here
}
class CallSlowService implements Callable<Result> {
@Override
Result call() throws Exception {
slowServiceClient.soooooSlow(request)
}
}
// Created using the "slowServiceDispatcher"
class SlowServiceActor extends UntypedActor {
@Override
void onReceive(Object message) {
if(message instanceof CallSlowService) {
Request request = (message as CallSlowService).request
Future<Result> callSlowServiceFuture = Futures.future(new CallSlowService())
Result result = ???
// ...now do something with result, some 15 seconds later
}
}
}
但正如你所看到的,我有几个问题:
- 我想我误解了
Futures.future(...)
API;我不认为这意味着构建新的Futures
- 我如何以非阻塞的方式实际获得
result
? - 最后:我错过了什么吗?我没有使用/利用我应该的任何策略?
我不特别理解akka,但对于基于一般事件的系统,不应该有一个不同的处理程序来处理来自缓慢服务的结果? –
Thanks @RajatGarg(+1) - * yes *,但该处理程序将需要一种方法,不仅可以调用回执行者系统,还可以执行该特定执行上下文中的特定执行者。在不知道Akka的情况下,您很难理解为什么这会使典型的回调/处理器解决方案不可行。 – smeeb