[英]Bulkheading strategies for Akka actors
I have a scenario where an important actor needs to make a call to a slow (15 - 20 seconds ) remote system: 我遇到了一个重要角色需要向慢速(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;
}
The Akka equivalent to this is currently looking like: 与此等效的Akka 当前看起来像:
// 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)
}
}
Obviously this is blocking and bad, bad, bad. 显然,这是障碍,坏,坏,坏。 After reading this excellent article on handling non-blocking DB calls , my main takeaway is that there are essentially two " bulkheading " strategies I can employ:
在阅读了有关处理非阻塞数据库调用的出色文章之后,我的主要收获是,我可以采用两种基本的“ 隔离 ”策略:
SlowServiceActor
instances in their own dispatcher, to isolate their latency/blocking-ness from other actors/threads that don't interact directly with the Slow Service; SlowServiceActor
实例放置在自己的调度程序中,以将其延迟/阻塞程度与未与Slow Service直接交互的其他actor /线程隔离开; and Futures
for true " asynchronicity " Futures
调用慢速服务以实现真正的“ 异步性 ” So my best attempt thus far is: 因此,到目前为止,我最大的尝试是:
// 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
}
}
}
But as you can see, I have a few problems: 但是如您所见,我有一些问题:
Futures.future(...)
API; Futures.future(...)
API; I don't think that's meant for constructing new Futures
Futures
result
in a non-blocking fashion? result
? If I understand this correctly, you kind of have two options here: you listen to a Future
being completed or you do something with the result: 如果我正确地理解了这一点,那么您在这里有两种选择:聆听
Future
的完成,或者对结果做一些事情:
If you want to listen, you can use some callback like 如果您想听,可以使用一些回调,例如
final ExecutionContext ec = system.dispatcher();
future.onSuccess(new OnSuccess<String>() {
public void onSuccess(String result) {
if ("bar" == result) {
//Do something if it resulted in "bar"
} else {
//Do something if it was some other String
}
}
}, ec);
The other way would be to map
the future's result. 另一种方法是
map
未来的结果。 So you have the something like: 所以你有类似的东西:
callSlowServiceFuture.map(new Mapper<ReturnType1, ReturnType2>() {
public ReturnType2 apply(ReturnType1 s) {
// do something with 's'
}
}, ec);
This way you say "... the moment I get a result from the service call, please manipulate it as described in apply ..." 这样一来,您说“ ...当我从服务电话获得结果时,请按照Apply ...中所述操作它。”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.