如何在将来取消时在Callable中终止CXF Web服务调用 [英] How to terminate CXF webservice call within Callable upon Future cancellation

查看:99
本文介绍了如何在将来取消时在Callable中终止CXF Web服务调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑

此问题到目前为止已经进行了几次迭代,因此随时查看修订内容以了解一些背景信息

This question has gone through a few iterations by now, so feel free to look through the revisions to see some background information on the history and things tried.

我正在同时使用CompletionService和ExecutorService和Callable,以同时调用通过CXF生成的代码在几个不同的Web服务上提供了许多功能。这些服务都为我用于项目的单个信息集贡献了不同的信息。但是,这些服务可能长时间不响应而不会引发异常,从而延长了对组合信息的等待时间。

I'm using a CompletionService together with an ExecutorService and a Callable, to concurrently call the a number of functions on a few different webservices through CXF generated code.. These services all contribute different information towards a single set of information I'm using for my project. The services however can fail to respond for a prolonged period of time without throwing an exception, prolonging the wait for the combined set of information.

为了解决这个问题,我正在运行所有服务并发调用,几分钟后想终止所有尚未完成的调用,最好从可调用对象内部或引发详细的Exception记录哪些尚未完成。

To counter this I'm running all the service calls concurrently, and after a few minutes would like to terminate any of the calls that have not yet finished, and preferably log which ones weren't done yet either from within the callable or by throwing an detailed Exception.

以下是一些高度简化的代码来说明我已经在做的事情:

Here's some highly simplified code to illustrate what I'm doing already:

private Callable<List<Feature>> getXXXFeatures(final WiwsPortType port, 
final String accessionCode) {
    return new Callable<List<Feature>>() {
        @Override
        public List<Feature> call() throws Exception {
            List<Feature> features = new ArrayList<Feature>();
            //getXXXFeatures are methods of the WS Proxy
            //that can take anywhere from second to never to return
            for (RawFeature raw : port.getXXXFeatures(accessionCode)) {
                Feature ft = convertFeature(raw);
                features.add(ft);
            }
            if (Thread.currentThread().isInterrupted())
                log.error("XXX was interrupted");
            return features;
        }
    };
}

同时启动WS调用的代码:

And the code that concurrently starts the WS calls:

WiwsPortType port = new Wiws().getWiws();
List<Future<List<Feature>>> ftList = new ArrayList<Future<List<Feature>>>();
//Counting wrapper around CompletionService, 
    //so I could implement ccs.hasRemaining()
CountingCompletionService<List<Feature>> ccs = 
        new CountingCompletionService<List<Feature>>(threadpool);
ftList.add(ccs.submit(getXXXFeatures(port, accessionCode)));
ftList.add(ccs.submit(getYYYFeatures(port accessionCode)));
ftList.add(ccs.submit(getZZZFeatures(port, accessionCode)));

List<Feature> allFeatures = new ArrayList<Feature>();
while (ccs.hasRemaining()) {
            //Low for testing, eventually a little more lenient
    Future<List<Feature>> polled = ccs.poll(5, TimeUnit.SECONDS);
    if (polled != null)
        allFeatures.addAll(polled.get());
    else {
        //Still jobs remaining, but unresponsive: Cancel them all
        int jobsCanceled = 0;
        for (Future<List<Feature>> job : ftList)
            if (job.cancel(true))
                jobsCanceled++;
        log.error("Canceled {} feature jobs because they took too long",
                        jobsCanceled);
        break;
    }
}

此代码存在的问题是在等待port.getXXXFeatures(...)返回时,可调用对象实际上并没有取消,但是以某种方式保持运行。从中可以看到,如果(Thread.currentThread()。isInterrupted())log.error( XXX被中断); 语句中,中断标志在port.getFeatures返回后设置,只有在Webservice调用正常完成后才可用,而不是在我调用Cancel时被中断。

The problem I'm having with this code is that the Callables aren't actually canceled when waiting for port.getXXXFeatures(...) to return, but somehow keep running. As you can see from the if (Thread.currentThread().isInterrupted()) log.error("XXX was interrupted"); statements the interrupted flag is set after port.getFeatures returns, this is only available after the Webservice call completes normally, instead of it having been interrupted when I called Cancel.

任何人都可以告诉我我做错了什么,如何在给定时间段内停止正在运行的CXF Webservice调用,并将此信息注册到我的应用程序中?

Can anyone tell me what I am doing wrong and how I can stop the running CXF Webservice call after a given time period, and register this information in my application?

最诚挚的问候,蒂姆

推荐答案

编辑3 新答案。

我看到以下选项:


  • 将您的问题作为功能请求发布到Apache CXF上

  • 自己修复ACXF并公开一些功能。

  • 在Apache CXF中寻找异步WS呼叫支持的选项

  • 考虑切换到其他WS提供程序( JAX-WS吗?)

  • 您的WS呼叫您自己吗? f如果服务支持,请使用RESTful API(例如带有参数的普通HTTP请求)

  • 仅适用于über专家:使用真实的线程/线程组并使用非传统方法杀死线程。

  • Post your problem on the Apache CXF as feature request
  • Fix ACXF yourself and expose some features.
  • Look for options for asynchronous WS call support within the Apache CXF
  • Consider switching to a different WS provider (JAX-WS?)
  • Do your WS call yourself using RESTful API if the service supports it (e.g. plain HTTP request with parameters)
  • For über experts only: use true threads/thread group and kill the threads with unorthodox methods.

这篇关于如何在将来取消时在Callable中终止CXF Web服务调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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