Java / Scala Future由回调驱动 [英] Java / Scala Future driven by a callback
问题描述
简短版本:
如何创建承诺<结果>
在触发回调时完成?
How can I create a Promise<Result>
which is completed on a trigger of a callback?
长版本:
我正在开发一个处理第三方SOAP服务的应用程序。来自用户的请求同时委托多个SOAP服务,聚合结果并发送回用户。
I am working on an application which deals with third-party SOAP services. A request from user delegates to multiple SOAP services simultaneously, aggregates the results and sends back to the user.
系统需要是可扩展的,并且应该允许多个并发用户。当每个用户请求最终触发大约10个Web服务调用并且每个呼叫阻塞大约1秒时,系统需要设计为具有非阻塞I / O.
The system needs to be scalable and should allow multiple concurrent users. As each user requests ends up triggering about 10 web service calls and each call blocking for about 1 second, the system needs to be designed with non-blocking I/O.
我在Play Framework(Java)中使用Apache CXF用于此系统。我已设法生成异步WS客户端代理并启用异步传输。我无法弄清楚当我委托多个Web服务代理时如何返回Future to Play的线程,结果将作为回调获得。
I am using Apache CXF within Play Framework (Java) for this system. I have managed to generate the Asynchronous WS Client proxies and enable the async transport. What I am unable to figure out is how to return a Future to Play's Thread when I have delegated to multiple Web Service proxies and the results will be obtained as callbacks.
选项1:使用返回Java Future的异步方法调用。
Option 1: Using async method calls returning Java Future.
如此scala.concurrent.Future包装为java.util.concurrent.Future 线程,我们无法转换为Scala未来的Java未来。从Future获得结果的唯一方法是执行阻止调用者的 Future.get()
。由于CXF生成的代理返回Java Future,因此排除了此选项。
As described in this scala.concurrent.Future wrapper for java.util.concurrent.Future thread, there is no way we can convert a Java Future to a Scala Future. Only way to get a result from the Future is to do Future.get()
which blocks the caller. Since CXF's generated proxies return Java Future, this option is ruled out.
选项2:使用Scala Future。
Option 2: Use Scala Future.
由于CXF生成代理接口,我不确定是否有任何方法可以干预并返回Scala Future(AFAIK Akka使用Scala Futures)而不是Java Future?
Since CXF generates the proxy interfaces, I am not sure if there is any way I can intervene and return a Scala Future (AFAIK Akka uses Scala Futures) instead of Java Future?
选项3:使用回调方法。
CXF生成的异步方法也返回Java Future接受一个回调对象,我想这会在结果准备好后提供回调。要使用这种方法,我需要返回一个等待我收到回调的Future。
The async methods generated by CXF which return Java Future also takes a callback object which I suppose will provide a callback when result is ready. To use this approach, I will need to return a Future which will wait until I receive a callback.
我认为选项3 最有希望虽然我对如何返回一个将在收到回调时完成的Promise没有任何想法。我可能有一个线程在中等待(true)
并等待,直到结果可用。再一次,我不知道如何在不阻塞线程的情况下进入等待
?
I think Option 3 is most promising, although I have no ideas about how I can return a Promise which will be completed on receiving a callback. I could possibly have a thread waiting in a while(true)
and waiting in between until result is available. Again, I don't know how I can go into wait
without blocking the thread?
简而言之,我正在尝试构建一个正在进行大量SOAP Web服务调用的系统,其中每个调用都会占用大量时间。在大量并发Web服务调用的情况下,系统可能很容易耗尽线程。我正在寻找一种基于非阻塞I / O的解决方案,它可以同时允许许多正在进行的Web服务调用。
In a nutshell, I am trying to build a system which is making a lot of SOAP web service calls, where each call blocks for significant time. The system may easily run out of threads in case of lot of concurrent web service calls. I am working on finding a solution which is non-blocking I/O based which can allow many ongoing web service calls at the same time.
推荐答案
选项3看起来不错:)开始使用几个导入...
Option 3 looks good :) A couple of imports to start with...
import scala.concurrent.{Await, Promise}
import scala.concurrent.duration.Duration
并且,只是为了说明重点是,这是一个采用回调的模拟CXF API:
and, just to illustrate the point, here's a mocked CXF API that takes the callback:
def fetch(url: String, callback: String => Unit) = {
callback(s"results for $url")
}
创建一个promise,使用promise作为回调调用API:
Create a promise, call API with promise as callback:
val promise = Promise[String]
fetch("http://corp/api", result => promise.success(result))
然后你可以将 promise.future
这是 Future
的一个实例带到你的Play应用程序中。
Then you can take promise.future
which is an instance of Future
into your Play app.
要测试它,你可以这样做:
To test it, you can do this:
Await.result(promise.future, Duration.Inf)
将阻止等待结果,此时您应该看到 http:// corp / api 在控制台中。
which will block awaiting the result, at which point you should see "results for http://corp/api" in the console.
这篇关于Java / Scala Future由回调驱动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!