Java / Scala Future由回调驱动 [英] Java / Scala Future driven by a callback

查看:190
本文介绍了Java / Scala Future由回调驱动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短版本:

如何创建承诺<结果> 在触发回调时完成?

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屋!

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