Java 阿克卡参与者的拓展策略
我有一个场景,一个重要的参与者需要呼叫一个缓慢(15-20秒)的远程系统:Java 阿克卡参与者的拓展策略,java,asynchronous,akka,blocking,future,Java,Asynchronous,Akka,Blocking,Future,我有一个场景,一个重要的参与者需要呼叫一个缓慢(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; } 与
// Non-actor code equivalent
public Result makeSlowNetworkCall(Request request) {
Result result = slowServiceClient.soooooSlow(request); // Could be up to 15 - 20 SECONDS (mehhhh)
return result;
}
与此类似的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)
}
}
显然,这是阻塞,糟糕,糟糕,糟糕。阅读后,我的主要收获是,我可以采用两种基本的“散装”策略:
- 将所有
实例放在它们自己的dispatcher中,以将它们的延迟/阻塞性与不直接与慢速服务交互的其他参与者/线程隔离开来;及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
}
}
}
//在application.conf中:
slowServiceDispatcher{
…在这里配置
}
类CallSlowService实现可调用{
@凌驾
结果调用()引发异常{
slowServiceClient.sooooslow(请求)
}
}
//使用“slowServiceDispatcher”创建
类SlowServiceActor扩展了UntypedActor{
@凌驾
void onReceive(对象消息){
if(CallSlowService的消息实例){
请求=(消息为CallSlowService)。请求
Future callSlowServiceFuture=Futures.Future(新的CallSlowService())
结果=???
//…现在做一些有结果的事情,大约15秒后
}
}
}
但正如你所看到的,我有几个问题:
- 我想我误解了未来(…)API;我认为这并不意味着要构建新的
未来
- 如何以非阻塞方式实际获得
结果
- 最后一点:我在这里遗漏了什么吗?我没有利用/利用我应该利用的任何策略
未来的正在完成,或者您对结果做一些事情:
如果你想听,你可以使用一些回调函数,比如
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);
通过这种方式,您可以说“…当我从服务调用中获得结果时,请按照应用中所述操作它…”我不太了解akka,但是对于基于一般事件的系统,是否应该有不同的处理程序来处理soo slow服务的结果?谢谢@RajatGarg(+1)-是,但是,该处理程序将需要一种方法,不仅可以回调到actor系统,还可以回调到特定执行上下文中的特定actor。如果不了解Akka,您将很难理解为什么这使得典型的回调/处理程序解决方案不可行。
callSlowServiceFuture.map(new Mapper<ReturnType1, ReturnType2>() {
public ReturnType2 apply(ReturnType1 s) {
// do something with 's'
}
}, ec);