簡體   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