我在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特别相关的解决方案,我决定提一下。
答案 0 :(得分:3)
我将@Hbf的答案标记为解决方案,因为我最终按照How do I wrap a java.util.concurrent.Future in an Akka Future?中的解释完成了Akka轮询。作为参考,我也尝试过:
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());
}
}
答案 1 :(得分:2)
与Scala期货相比,已知Java期货在设计方面较差。例如,查看讨论"How do I wrap a java.util.concurrent.Future in an Akka Future"。
但是:也许,Hystrix提供某种onComplete
回调,而不是轮询(如上面的讨论所示)?我根本不知道图书馆,但偶然发现onComplete
in the Hystrix API。也许有帮助?
答案 2 :(得分:2)
从Hystrix 1.3开始,它现在也支持真正的非阻塞回调,并且更适合非阻塞和可组合的Akka / Scala Future行为:https://github.com/Netflix/Hystrix/wiki/How-To-Use#wiki-Reactive-Execution