【发布时间】:2010-06-25 19:37:29
【问题描述】:
我正在编写一个集成 web 服务,它将使用来自几个不同后端系统的各种 web 服务。我希望能够并行化非依赖服务调用,并能够取消耗时过长的请求(因为我要满足 SLA)。
为了帮助并行后端调用,我使用 ASYNC 客户端 API(由 wsimport 使用客户端 jax-ws 绑定更改文件生成)
我遇到的问题是,当我尝试取消请求时,Response 适当地将请求标记为已取消,但实际请求并未真正取消。显然,JAX-WS 运行时的某些部分实际上将 com.sun.xml.ws.api.pipe.Fiber 提交到运行队列,这实际上是请求的内容。 Result 上的取消不会阻止这些 PIPE 在队列上运行并发出请求。
以前有没有人遇到过这个问题或类似的问题?
我的代码如下所示:
List<Response<QuerySubscriberResponse>> resps = new ArrayList<Response<QuerySubscriberResponse>>();
for (int i = 0; i < 10; i++) {
resps.add(FPPort.querySubscriberAsync(req));
}
for (int i = 0; i < 10; i++) {
logger.info("Waiting for " + i);
try {
QuerySubscriberResponse re = resps.get(i).get(1,
TimeUnit.SECONDS); // execution time for this request is 15 seconds, so we should always get a TimeoutException
logger.info("Got: "
+ new Marshaller().marshalDocumentToString(re));
} catch (TimeoutException e) {
logger.error(e);
logger.error("Cancelled: " + resps.get(i).cancel(true));
try {
logger.info("Waiting for my timed out thing to finish -- technically I've canceled it");
QuerySubscriberResponse re = resps.get(i).get(); // this causes a CancelledExceptio as we would expect
logger.info("Finished waiting for the canceled req");
} catch (Exception e1) {
e1.printStackTrace();
}
} catch (Exception e) {
logger.error(e);
} finally {
logger.info("");
logger.info("");
}
}
我希望所有这些请求最终都会被取消,但实际上它们都会继续执行,并且只有在后端最终决定向我们发送响应时才返回。
【问题讨论】:
-
我忘了提到 WLS 10.3.3 提供了来自 glass-fish 的非库存 JAX-WS 2.1.5 参考实现。我说非库存是因为他们显然修改了相当多的代码。这种行为可能是由于此修改引入的一些错误造成的吗?还是因为我不了解异步 API 的语义?
-
我创建了一个博客来跟踪我正在尝试回答这个问题的进度和步骤/测试:differentframeofmind.blogspot.com
-
事实证明这确实是 jax-ws 实现中的一个错误。 Oracle 已针对 wls 10.3.3 发布补丁 (RHEL) 以解决此问题。
标签: asynchronous weblogic jax-ws