当前位置: 首页 > 知识库问答 >
问题:

回调驱动的Java/Scala未来

弓宏茂
2023-03-14

简短版:

如何创建Promise

长版本:

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

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

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

选项1:使用异步方法调用并在将来返回Java。

如本scala.concurrent中所述。java.util.concurrent的未来包装器。对于未来线程,我们无法将Java未来转换为Scala未来。从未来获得结果的唯一方法是在未来执行操作。get(),它阻止调用者。由于CXF生成的代理将来返回Java,因此不考虑此选项。

选项2:使用Scala Future。

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

选项 3:使用回调方法。

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

我认为选择3是最有希望的,尽管我不知道如何在收到回电时兑现promise。我可能会让一个线程在< code>while(true)中等待,并在两者之间等待,直到结果可用。同样,我不知道如何在不阻塞线程的情况下进入< code>wait?

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

共有1个答案

强才捷
2023-03-14

选项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,调用 API,将 promise 作为回调:

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

然后你可以接受<code>promise。future,它是您的Play应用程序中<code>future</code>的一个实例。

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

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

这将阻止等待结果,在这一点上,您应该看到“结果”http://corp/api“在控制台中。

 类似资料:
  • 在一个无状态bean中,我正在查找队列,这是正确的,并且发送没有抛出异常: 但不调用消息驱动bean的onMessage方法。 我错过了什么? 我的消息驱动bean有以下代码:

  • 我有一个对象,我想将其转换为

  • 我有一个Scala future,它调用一个api并返回future,如果结果不正确,那么另一个api调用将与第一个future的结果一起提交并作为future返回。 这是我目前为止所拥有的。 但是如果我访问fut2结果,它会给出这样的结果: 有没有一种方法,我可以选择返回fot2,如果fot1的结果是不准确的? 编辑:第二个未来必须使用第一个未来来继续API调用。这就是我到目前为止所拥有的。

  • 我想使用Mongo-Scala驱动程序创建一个集合的唯一索引。这个驱动程序是新的,我也是Scala的新手。我无法通过这两种方法创建索引。 还有这个: 有没有人可以帮助如何在Mongo-Scala驱动程序中创建唯一的索引,因为它是非常新的,没有太多的信息可用。

  • 我有以下方法,用于返回Play for Scala应用程序中的字符串列表: } 代码不会编译并出现以下错误,因为如果 access = 0,则结果不是 Future: 类型不匹配;找到:play.api.mvc.Result要求:scala.concurrent.Future[play.api.mvc.Result] 如何解决这个问题?

  • 我用的是Scala 2.10,Akka 2.1和Play 2.1。当我向后端发送一个http请求时,我要求一个参与者计算一些东西。如果计算结果在超时之前返回,则返回计算结果,否则返回另一个字符串。请参阅下面的代码。 演员如下: 我的问题是,即使演员在超时之前完成,未来也不会“返回”任何内容,因此超时总是过期。我做错了什么?谢谢。