如何在Akka Future中包装java.util.concurrent.Future? [英] How do I wrap a java.util.concurrent.Future in an Akka Future?

查看:112
本文介绍了如何在Akka Future中包装java.util.concurrent.Future?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In a Play Framework 2.0.1 (Scala) application, we are using a web service client library which returns java.util.concurrent.Future as responses.

我们希望将j.u.c.Future包装在akka.dispatch.Future中,而不是在get()调用上阻止Play应用,以便我们可以轻松地使用play框架的AsyncResult处理.

Instead of blocking the Play app on the get() call, we'd like to wrap the j.u.c.Future in an akka.dispatch.Future, so that we can easily use the play framework's AsyncResult processing.

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

Has anyone done this before, or have a library or example code?

更新:我们找到的最接近的是这个Google网上论坛讨论:

UPDATE: The closest thing we've found is this google groups discussion: https://groups.google.com/forum/#!topic/play-framework/c4DOOtGF50c

...如果您拥有的只是一个简单的jucFuture,那么创建一个非阻塞解决方案的最佳办法就是采用jucFuture和一个Promise,然后将它们提供给运行轮询循环的某个线程,以完成轮询操作.完成时对未来的结果作出承诺.

...if all you have is a plain j.u.c.Future the best you can do to create a non blocking solution is to take the j.u.c.Future and a Promise, and give them to some thread running a polling loop that will complete the Promise with the result of the Future when it is done.

有人有这样的示例实现吗?

Does anyone have an example implementation of this?

推荐答案

@Viktor Klang:我们知道j.u.c.Future是可憎的.但这就是我们从暂时必须接受的软件中得到的回报.

@Viktor Klang: We understand that j.u.c.Future is an abomination. But that's what we're getting back from a piece of software we must accept as given for the time being.

到目前为止,这是我们共同努力的目标:

So far, this is what we've hacked together:

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
}

换句话说,创建对应于j.u.c.Future的单独的Akka Promise(Future的写端),启动回调pollJavaFutureUntilDoneOrCancelled以通过轮询憎恶"来更新Promise,并将Promise退还给呼叫者.

In other words, create a separate Akka Promise (the write-side of a Future) corresponding to the j.u.c.Future, kicks off the callback pollJavaFutureUntilDoneOrCancelled to update the Promise by polling the "abomination", and returns the Promise to the caller.

那么我们如何根据j.u.c.Future的状态来轮询"更新Akka Promise?

So how do we "poll" to update the Akka Promise based on the state of the j.u.c.Future?

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.

This is an attempt at what was hinted at in the google groups discussion that I referenced in the question. It uses the Akka scheduler to call itself back every 50 ms to check if the j.u.c.Future is either done or cancelled. Whenever that happens, it updates the Akka Promise with the completed state.

@Victor Klang等:

@Victor Klang, et al:

这是最佳做法吗?您知道更好的方法吗?我们在这里缺少应该知道的缺点吗?

Is this best practice? Do you know of a better way to do this? Are we missing a downside here that we should know about?

感谢您的帮助.

这篇关于如何在Akka Future中包装java.util.concurrent.Future?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆