【问题标题】:Java / Scala Future driven by a callback由回调驱动的 Java / Scala Future
【发布时间】:2015-09-06 12:46:38
【问题描述】:

短版:

如何创建在触发回调时完成的Promise<Result>

加长版:

我正在开发一个处理第三方 SOAP 服务的应用程序。来自用户的请求同时委托给多个 SOAP 服务,汇总结果并发回给用户。

系统需要具有可扩展性,并且应该允许多个并发用户。由于每个用户请求最终会触发大约 10 个 Web 服务调用,并且每个调用阻塞大约 1 秒,因此系统需要设计为非阻塞 I/O。

我在该系统的 Play Framework (Java) 中使用 Apache CXF。我已经设法生成异步 WS 客户端代理并启用异步传输。我无法弄清楚当我委托给多个 Web 服务代理时如何将 Future 返回到 Play 的线程并且结果将作为回调获得。

选项 1:使用异步方法调用返回 Java Future。

正如scala.concurrent.Future wrapper for java.util.concurrent.Future 线程中所述,我们无法将 Java Future 转换为 Scala Future。从 Future 获得结果的唯一方法是执行 Future.get() 阻止调用者。由于 CXF 生成的代理返回 Java Future,因此该选项被排除。

选项 2: 使用 Scala Future。

由于 CXF 生成代理接口,我不确定是否有任何方法可以干预并返回 Scala Future(AFAIK Akka 使用 Scala Futures)而不是 Java Future?

选项 3:使用回调方法。

由 CXF 生成的返回 Java Future 的异步方法也接受一个回调对象,我想它会在结果准备好时提供一个回调。要使用这种方法,我需要返回一个 Future,它会等到我收到回调。

我认为 选项 3 最有前途,尽管我不知道如何返回一个 Promise,该 Promise 将在收到回调时完成。我可能有一个线程在 while(true) 中等待并在两者之间等待,直到结果可用。再说一次,我不知道如何在不阻塞线程的情况下进入wait

简而言之,我正在尝试构建一个进行大量 SOAP Web 服务调用的系统,其中每个调用都会阻塞很长时间。在大量并发 Web 服务调用的情况下,系统可能很容易耗尽线程。我正在寻找一种基于非阻塞 I/O 的解决方案,它可以同时允许许多正在进行的 Web 服务调用。

【问题讨论】:

  • 惊讶于 4 票以结束问题,即使我有一个非常精确的较短版本的问题。

标签: java scala playframework-2.0 akka nonblocking


【解决方案1】:

选项 3 看起来不错 :) 从几个导入开始...

import scala.concurrent.{Await, Promise}
import scala.concurrent.duration.Duration

并且,为了说明这一点,这里有一个模拟的 CXF API,它接受回调:

def fetch(url: String, callback: String => Unit) = {
  callback(s"results for $url")
}

创建一个promise,以promise作为回调调用API:

val promise = Promise[String]
fetch("http://corp/api", result => promise.success(result))

然后,您可以将promise.futureFuture 的一个实例)带入您的 Play 应用。

要对其进行测试,您可以这样做:

Await.result(promise.future, Duration.Inf)

这将阻止等待结果,此时您应该会在控制台中看到“http://corp/api 的结果”。

【讨论】:

  • 感谢示例代码,尽管我使用的是 Play Java。我认为我缺少的一点是Promise 正是实现这一目标的东西。如果是 Play Java,则为 play.libs.F.RedeemablePromise。所以我可以返回一个RedeemablePromise 的实例并传递javax.xml.ws.AsyncHandler 的句柄,其中嵌入了promise 对象,以便回调对象可以通过success() 调用委托给promise。我想我现在明白了 Future 和 Promise 之间的区别,我曾经认为它们非常相似。
  • 我已经设法使用Promise 进行异步工作。谢谢@bjfletcher
猜你喜欢
  • 2016-11-19
  • 2016-05-04
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2016-11-10
  • 1970-01-01
  • 2017-08-02
  • 2015-10-10
相关资源
最近更新 更多