繁体   English   中英

如何使用Akka actor处理Java期货

[英]How to handle Java futures with Akka actors

我在Java Web应用程序中有一个分层架构。 UI层只是Java,服务是类型化的Akka actor,外部服务调用(WS,DB等)包含在Hystrix命令中。

UI调用服务,服务返回Akka未来。 这是Akka的未来,因为我希望使用Akka期货提供的onComplete和onFailure回调来简化UI编码。 然后,该服务创建执行某些映射等的未来,并将调用包装回返回Java未来的HystrixCommand。

所以在伪代码中:

UI

AkkaFuture future = service.getSomeData();

服务

public AkkaFuture getSomeData() {
    return future {
        JavaFuture future = new HystrixCommand(mapSomeData()).queue()
        //what to do here, currently just return future.get()
    }
}

问题是我想释放服务主角正在使用的线程,并且只是绑定Hystrix使用的线程。 但是java的未来会阻止它,因为我必须阻止它的完成。 我能想到的唯一选择(我不确定自己喜欢)是不断轮询Java未来,并在Java未来完成时完成Akka的未来。

注意:问题与Hystrix本身并没有真正的关系,但如果有人想出一个与Hystrix特别相关的解决方案,我决定提一下。

我正在用@Hbf作为解决方案来标记答案,因为我最终做了一个Akka poller,如在Akka Future如何包装java.util.concurrent.Future中所述? 作为参考,我也尝试过:

  • 创建HystrixCommandExcutionHook并扩展HystrixCommand以允许回调。 这没有用,因为没有在正确的时间调用钩子。
  • 通过装饰执行器使用Guavas可听的未来在Hystrix内创建未来,然后从命令中转换期货。 不起作用,因为Hystrix使用无法装饰的ThreadPoolExecutor。

编辑:我在下面添加了Akka轮询代码,因为最初的答案是在Scala中,如果Java未来不能很好地取消它会挂起。 下面的解决方案总是在超时后离开线程。


    protected  Future wrapJavaFutureInAkkaFuture(final java.util.concurrent.Future javaFuture, final Option maybeTimeout, final ActorSystem actorSystem) {
      final Promise promise = Futures.promise();
        if (maybeTimeout.isDefined()) {
          pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, Option.option(maybeTimeout.get().fromNow()), actorSystem);
        } else {
          pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, Option. none(), actorSystem);
        }

        return promise.future();
    }

    protected  void pollJavaFutureUntilDoneOrCancelled(final java.util.concurrent.Future javaFuture, final Promise promise, final Option maybeTimeout, final ActorSystem actorSystem) {
      if (maybeTimeout.isDefined() && maybeTimeout.get().isOverdue()) {
        // on timeouts, try to cancel the Java future and simply walk away
        javaFuture.cancel(true);
        promise.failure(new ExecutionException(new TimeoutException("Future timed out after " + maybeTimeout.get())));

      } else if (javaFuture.isDone()) {
        try {
          promise.success(javaFuture.get());
        } catch (final Exception e) {
          promise.failure(e);
        }
      } else {
            actorSystem.scheduler().scheduleOnce(Duration.create(50, TimeUnit.MILLISECONDS), new Runnable() {
          @Override
          public void run() {
            pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, maybeTimeout, actorSystem);
          }
        }, actorSystem.dispatcher());
      }
    }

与Scala期货相比,已知Java期货在设计上较差。 例如,看看讨论“如何在Akka Future中包装java.util.concurrent.Future”

但是:也许,而不是轮询(如上面的讨论所示),Hystrix提供某种onComplete回调? 我根本不知道这个库,但偶然发现了Hystrix API中onComplete 也许有帮助吗?

从Hystrix 1.3开始,它现在也支持真正的非阻塞回调,并且非常适合非阻塞和可组合的Akka / Scala Future行为: https//github.com/Netflix/Hystrix/wiki/How-To -使用#维基无功执行

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM