Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 阿克卡参与者的拓展策略_Java_Asynchronous_Akka_Blocking_Future - Fatal编程技术网

Java 阿克卡参与者的拓展策略

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; } 与

我有一个场景,一个重要的参与者需要呼叫一个缓慢(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;
}
与此类似的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)
    }
}
显然,这是阻塞,糟糕,糟糕,糟糕。阅读后,我的主要收获是,我可以采用两种基本的“散装”策略:

  • 将所有
    SlowServiceActor
    实例放在它们自己的dispatcher中,以将它们的延迟/阻塞性与不直接与慢速服务交互的其他参与者/线程隔离开来;及
  • 通过
    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);