2009-07-13 50 views
1

编辑如何在未来消除内可赎回终止CXF Web服务调用

这个问题已经通过几次迭代过去了,现在,可以随意通过修订看看,看看历史上和一些事情的背景资料试过。


我使用CompletionService连同一个ExecutorService和赎回,并发调用多项功能于几个不同的服务通过CXF生成的代码。这些服务都有助于对一组不同的信息我用于我的项目的信息。然而,这些服务可能无法长时间响应而没有抛出异常,延长了组合信息的等待时间。

为了解决这个问题,我正在运行的所有服务同时调用,并在几分钟后想终止任何尚未完成的呼叫,最好登录哪些没有做但无论是从内可调用或通过抛出一个详细的例外。

下面是一些高度简化的代码来说明我在做什么已经:

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代码调用:

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(...)返回时,实际上并没有取消Callables,但以某种方式继续运行。正如你可以从if (Thread.currentThread().isInterrupted()) log.error("XXX was interrupted");声明中断标志是port.getFeatures返回后集看,这是唯一可用的Web服务调用正常完成之后,而不是当我打电话取消它已被打断。

谁能告诉我,在给定的时间段后什么,我做错了,我怎么能停止正在运行的CXF Web服务调用,并注册在我的应用程序的信息?

最好的问候,蒂姆

+0

要捕获里面的内容,请使用isCancelled()方法。如果您在等待/ IO上被阻止,您的取消呼叫也会在内部导致InterruptedException。 – akarnokd 2009-07-13 21:57:13

+0

isCancelled()仅在Future上可用,而我的代码驻留在Callable中,因此第一行不会起作用。至于第二行:我试过(但正如我所说,很糟糕)以捕获任何类型的异常在Callable中,但是迄今为止无法这样做..将InterruptException中的call()中的所有行包含在try/catch块中会因为无法访问的catch块异常而失败,因为Exception永远不会从try语句主体。 (或者说Eclipse说;))是否有可怕的Thread类中有任何丑陋的旧东西可以在这里帮助? – Tim 2009-07-13 22:32:07

回答

2

编辑3新的答案。

我看到这些选项:

  • 安置自己的Apache CXF问题,功能要求
  • 修复ACXF自己,暴露了一些功能。
  • 查找中的Apache CXF
  • 异步WS通话支持选项考虑切换到不同的WS提供商(JAX-WS?)
  • 做你的WS称自己使用的RESTful API,如果该服务支持的话(例如纯带参数的HTTP请求)
  • 对于尤伯杯专家只:用真实的线程/线程组和杀死非正统的方法的线程。