Pergunta

Editar

Esta questão passou por algumas iterações até agora, tão à vontade para olhar através das revisões para ver algumas informações básicas sobre a história e as coisas tentado.


Eu estou usando um CompletionService juntamente com um ExecutorService e uma mobilizável, para chamar simultaneamente a uma série de funções em algumas webservices diferentes através de código CXF gerado .. Estes serviços contribuem informações diferentes para um único conjunto de informações I' estou usando para o meu projeto. Os serviços, porém, pode não responder por um período prolongado de tempo sem lançar uma exceção, prolongando o tempo de espera para o conjunto combinado de informações.

Para contrariar esta situação eu estou correndo todas as chamadas de serviço ao mesmo tempo, e depois de alguns minutos, gostaria de encerrar qualquer das chamadas que ainda não terminaram, e de preferência log quais não foram feitos ainda quer a partir de dentro do que pode ser chamado ou lançando uma exceção detalhado.

Aqui está um código altamente simplificado para ilustrar o que estou fazendo já:

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;
        }
    };
}

E o código que simultaneamente inicia as chamadas 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;
    }
}

O problema que estou tendo com este código é que os Callables na verdade não são cancelados quando esperando port.getXXXFeatures (...) para retornar, mas de alguma forma continuar correndo. Como você pode ver a partir das declarações if (Thread.currentThread().isInterrupted()) log.error("XXX was interrupted"); a bandeira interrompido é definido após port.getFeatures retornos, este só está disponível depois da conclusão do atendimento Webservice normalmente, ao invés de ter sido interrompido quando liguei Cancelar.

Alguém pode me dizer o que estou fazendo de errado e como posso parar a correr chamada CXF Webservice após um determinado período de tempo, e registrar essas informações na minha candidatura?

Com os melhores cumprimentos, Tim

Foi útil?

Solução

Editar 3 New resposta.

Eu vejo estas opções:

  • Post seu problema no CXF Apache como pedido de recurso
  • Corrija ACXF-se e expor alguns recursos.
  • Procure opções para suporte chamada WS assíncrono dentro do Apache CXF
  • Considere mudar para outro provedor de WS (JAX-WS?)
  • Faça o seu WS chamar-se usando a API RESTful se os suportes de Serviços de TI (por exemplo solicitação HTTP simples com parâmetros)
  • Para os peritos só über:. Uso true / grupo de discussão tópicos e matar os fios com métodos pouco ortodoxos

Outras dicas

Os docs CXF ter algumas instruções para configurar o tempo limite de leitura na HttpURLConnection: http://cwiki.apache.org/CXF20DOC/ client-http-transporte, incluindo-ssl-support.html

Isso provavelmente satisfazer as suas necessidades. Se o servidor não responder em tempo, uma exceção é levantada e o que pode ser chamado iria receber a exceção. (Exceto que há um bug onde é pode travar em seu lugar. Não me lembro se isso foi corrigido para 2.2.2 ou se é apenas nos instantâneos agora.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top