14

在 Play Framework 2.0.1 (Scala) 应用程序中,我们使用了java.util.concurrent.Future作为响应返回的 Web 服务客户端库。

get()我们不想在调用时阻止 Play 应用程序,而是将 包装j.u.c.Future在一个 中akka.dispatch.Future,以便我们可以轻松地使用播放框架的AsyncResult处理。

有没有人这样做过,或者有一个库或示例代码?


更新:我们发现最接近的是这个谷歌群组讨论:https ://groups.google.com/forum/#!topic/play-framework/c4DOOtGF50c

...如果您所拥有的只是一个普通的 jucFuture,那么创建非阻塞解决方案的最佳方法是获取 jucFuture 和 Promise,并将它们提供给运行轮询循环的某个线程,该循环将完成 Promise,其结果为完成后的未来。

有没有人有这个的示例实现?

4

2 回答 2

7

@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
}

换句话说,创建Promise一个Futurej.u.c.FuturepollJavaFutureUntilDoneOrCancelled

那么我们如何根据 jucFuture 的状态“轮询”来更新 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 毫秒回调一次,以检查 jucFuture 是完成还是取消。每当发生这种情况时,它都会将 Akka Promise 更新为完成状态。

@Victor Klang 等人:

这是最佳实践吗?你知道更好的方法吗?我们是否错过了我们应该知道的缺点?

感谢您提供更多帮助。

于 2012-07-18T21:17:07.460 回答
0

您应该使用akka.dispatch.Futures.future()with java.util.concurrent.Callable

val akkaFuture: akka.dispatch.Future[String] = akka.dispatch.Futures.future(
  new java.util.concurrent.Callable[String] {
    def call: String = {
      return "scala->" + javaFuture.get
    }
}, executionContext)

完整示例的要点

于 2013-06-26T12:26:53.903 回答