Domanda

Modifica

Questa domanda ha attraversato alcune iterazioni, ormai, quindi sentitevi liberi di guardare attraverso le revisioni per vedere alcune informazioni di base sulla storia e le cose provato.


Io sto usando un CompletionService insieme a un ExecutorService e Callable, per chiamare contemporaneamente l'una serie di funzioni su alcuni servizi web differenti attraverso CXF codice generato .. Tali servizi contribuiscono informazioni diverse verso un unico insieme di informazioni che ho' m usando per il mio progetto. I servizi tuttavia possono non rispondere per un periodo prolungato di tempo senza un'eccezione, prolungando l'attesa per l'insieme combinato delle informazioni.

Per contrastare questo sto correndo tutte le chiamate di servizio contemporaneamente, e dopo pochi minuti piacerebbe terminare qualsiasi delle chiamate che non hanno ancora finito, e preferibilmente il login quali non erano ancora né dall'interno del callable fatto o con un'eccezione dettagliata.

Ecco un po 'di codice molto semplificato per illustrare quello che sto facendo già:

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 il codice che inizia contemporaneamente la WS chiama:

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

Il problema che sto avendo con questo codice è che i callable non sono effettivamente cancellati quando in attesa di port.getXXXFeatures (...) per tornare, ma in qualche modo continuare a correre. Come si può vedere dalle dichiarazioni if (Thread.currentThread().isInterrupted()) log.error("XXX was interrupted"); bandiera interrotto è set dopo port.getFeatures ritorni, questo è disponibile solo dopo la chiamata Webservice completa normalmente, invece di esso essendo stato interrotto quando ho chiamato Annulla.

Qualcuno può dirmi quello che sto facendo di sbagliato e come posso fermare l'esecuzione chiamata Webservice CXF dopo un determinato periodo di tempo, e registrare queste informazioni nella mia domanda?

Con i migliori saluti, Tim

È stato utile?

Soluzione

Modifica 3 Nuova risposta.

vedo queste opzioni:

  • Inserisci il tuo problema sul Apache CXF come richiesta di funzione
  • Fissare ACXF te stesso ed esporre alcune caratteristiche.
  • cercare le opzioni per il supporto chiamata WS asincrono all'interno di Apache CXF
  • in considerazione il passaggio a un altro fornitore di WS (JAX-WS?)
  • Fare il vostro WS chiamano da soli, usando RESTful API, se il servizio supporta (ad esempio richiesta HTTP pianura con i parametri)
  • Per gli esperti über solo:. Utilizzare true / gruppo di thread discussioni e uccidere i fili con metodi poco ortodossi

Altri suggerimenti

La documentazione CXF hanno alcune istruzioni per impostare il timeout di lettura sul HttpURLConnection: http://cwiki.apache.org/CXF20DOC/ client-http-trasporto-compresi-ssl-support.html

Che probabilmente soddisfare le vostre esigenze. Se il server non risponde in tempo, viene sollevata un'eccezione e richiamabile otterrebbe l'eccezione. (A meno che ci sia un bug in cui è invece potrebbe bloccarsi. Non riesco a ricordare se che è stato fissato per il 2.2.2 o se è solo nelle istantanee al momento.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top