Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
回调驱动的Java/Scala未来_Java_Scala_Playframework 2.0_Akka_Nonblocking - Fatal编程技术网

回调驱动的Java/Scala未来

回调驱动的Java/Scala未来,java,scala,playframework-2.0,akka,nonblocking,Java,Scala,Playframework 2.0,Akka,Nonblocking,短版: 如何创建在回调触发时完成的承诺 长版本: 我正在开发一个处理第三方SOAP服务的应用程序。来自用户的请求同时委托给多个SOAP服务,聚合结果并发送回用户 系统需要具有可扩展性,并应允许多个并发用户。由于每个用户请求最终会触发大约10个web服务调用,并且每个调用会阻塞大约1秒,因此系统需要设计为非阻塞I/O 我正在为这个系统使用ApacheCXFinPlayFramework(Java)。我已经成功地生成了异步WS-Client代理并启用了异步传输。我无法弄清楚的是,当我委托给多个Web

短版:

如何创建在回调触发时完成的
承诺

长版本:

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

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

我正在为这个系统使用ApacheCXFinPlayFramework(Java)。我已经成功地生成了异步WS-Client代理并启用了异步传输。我无法弄清楚的是,当我委托给多个Web服务代理,结果将作为回调获得时,如何返回Future to Play的线程

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

如本线程所述,我们无法将Java未来转换为Scala未来。从未来获取结果的唯一方法是执行
Future.get()
,这会阻止调用方。由于CXF生成的代理返回Java Future,因此排除了此选项

选项2:使用Scala Future

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

选项3:使用回调方法

CXF生成的返回Java Future的异步方法还接受一个callback对象,我认为当结果准备好时,该对象将提供一个回调。要使用这种方法,我需要返回一个Future,它将等待我收到回调

我认为选项3是最有希望的,尽管我不知道如何在收到回电后返回承诺。我可能有一个线程在
中等待,而(true)
则在这两者之间等待,直到结果可用。同样,我不知道如何进入
wait
而不阻塞线程

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

选项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")
}
val promise = Promise[String]
fetch("http://corp/api", result => promise.success(result))
创建承诺,使用承诺作为回调调用API:

def fetch(url: String, callback: String => Unit) = {
  callback(s"results for $url")
}
val promise = Promise[String]
fetch("http://corp/api", result => promise.success(result))
然后你可以将
promise.future
这是
future
的一个实例带到你的Play应用程序中

要测试它,可以执行以下操作:

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

这将阻止等待结果,此时您应该在控制台中看到“results for”。

感谢示例代码,尽管我使用的是Play Java。我想我遗漏的一点是,
承诺
正是实现这一目标的关键。对于Play Java,它是
Play.libs.F.retainablepromise
。因此,我可以返回一个
ReceivablePromise
的实例,并传递
javax.xml.ws.AsyncHandler
的句柄,该句柄中嵌入了promise对象,以便回调对象可以通过
success()
调用委托到promise中。我想我理解了Future和Promise now之间的区别,我过去认为它们非常相似。我使用
Promise
实现了异步工作。感谢@bjfletchers以4票的优势结束了这个问题,即使我有一个非常精确的简短问题。