Pregunta

Editar

Esta cuestión ha pasado por unas pocas iteraciones por ahora, por lo que no dude en mirar a través de las revisiones de ver algo de información sobre la historia y cosas tratado.


Estoy usando un CompletionService junto con un ExecutorService y una rescatable, a llamar al mismo tiempo el una serie de funciones en unos pocos servicios web a través de diferentes CXF Código generado .. Estos servicios contribuyen información diferente hacia un único conjunto de información I' estoy usando para mi proyecto. sin embargo, los servicios pueden dejar de responder durante un período prolongado de tiempo sin lanzar una excepción, prolongando la espera para el conjunto combinado de la información.

Para contrarrestar esto que estoy corriendo todo el servicio de llamadas al mismo tiempo, y después de unos minutos gustaría terminar cualquiera de las llamadas que aún no han terminado, y preferiblemente registrar cuáles no se realizaron sin embargo, ya sea desde dentro de la exigible o por lanzar una excepción detallada.

Aquí hay un código muy simplificado para ilustrar lo que estoy haciendo ya:

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

Y el código que al mismo tiempo se inicia la WS llama:

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

El problema que estoy teniendo con este código es que los callables no se cancelan cuando en realidad la espera de port.getXXXFeatures (...) para volver, pero de alguna manera siguen en ejecución. Como se puede ver en las sentencias if (Thread.currentThread().isInterrupted()) log.error("XXX was interrupted"); la bandera interrumpe es set después de port.getFeatures rendimientos, esto sólo está disponible después de la llamada de servicio web se completa con normalidad, en lugar de haber sido interrumpida que cuando llamé Cancelar.

Puede alguien decirme lo que estoy haciendo mal y cómo puedo detener el funcionamiento de llamada de servicio web CXF después de un período de tiempo determinado, y registrar esta información en mi solicitud?

Saludos, Tim

¿Fue útil?

Solución

Editar 3 Nueva respuesta.

Veo estas opciones:

  • Publique problema en el CXF Apache como solicitud de función
  • Fijar ACXF mismo y exponer algunas características.
  • Busque opciones de apoyo llamada WS asíncrona dentro del Apache CXF
  • considerar el cambio a un proveedor de WS diferente (JAX-WS?)
  • Haga su WS llaman a sí mismo utilizando la API REST si el servicio lo permite (por ejemplo solicitud HTTP normal con parámetros)
  • Para los expertos über solamente:. Utilizar cierto grupo de hilos / hilo y matar los hilos con métodos poco ortodoxos

Otros consejos

Los documentos CXF tienen algunas instrucciones para configurar el tiempo de espera de lectura en el HttpURLConnection: http://cwiki.apache.org/CXF20DOC/ cliente-http-transporte-incluidos-ssl-support.html

Eso probablemente satisfacer sus necesidades. Si el servidor no responde en el tiempo, se produce una excepción y el exigible obtendría la excepción. (Excepto que hay un error en el que se puede colgar en su lugar. No puedo recordar si ese mismo fijada para el 2.2.2 o si es sólo en las instantáneas en este momento.)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top