@Viktor Klang:我们知道j.u.c.Future 是可憎的。但这就是我们从一个我们必须暂时接受的软件中得到的回报。
到目前为止,这是我们一起破解的:
def wrapJavaFutureInAkkaFuture[T](javaFuture: java.util.concurrent.Future[T], maybeTimeout: Option[Duration] = None)(implicit system: ActorSystem): akka.dispatch.Future[T] = {
val promise = new akka.dispatch.DefaultPromise[T]
pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, maybeTimeout.map(_.fromNow))
promise
}
换句话说,创建一个单独的 Akka Promise(Future 的写入端)对应于 j.u.c.Future,启动回调 pollJavaFutureUntilDoneOrCancelled 以通过轮询“可憎”来更新 Promise,并将 Promise 返回给调用者。
那么我们如何“轮询”以根据 j.u.c.Future 的状态更新 Akka Promise?
def pollJavaFutureUntilDoneOrCancelled[T](javaFuture: java.util.concurrent.Future[T], promise: akka.dispatch.Promise[T], maybeDeadline: Option[Deadline] = None)(implicit system: ActorSystem) {
if (maybeDeadline.exists(_.isOverdue)) javaFuture.cancel(true);
if (javaFuture.isDone || javaFuture.isCancelled) {
promise.complete(allCatch either { javaFuture.get })
} else {
Play.maybeApplication.foreach { implicit app =>
system.scheduler.scheduleOnce(50 milliseconds) {
pollJavaFutureUntilDoneOrCancelled(javaFuture, promise, maybeDeadline)
}
}
}
}
这是对我在问题中引用的 google 群组讨论中暗示的内容的尝试。它使用 Akka 调度程序每 50 毫秒回调一次,以检查 j.u.c.Future 是完成还是取消。每当发生这种情况时,它都会将 Akka Promise 更新为完成状态。
@Victor Klang 等人:
这是最佳做法吗?你知道更好的方法吗?我们是否错过了我们应该知道的缺点?
感谢您提供更多帮助。