Question

Modifier

Cette question est passé par quelques itérations maintenant, alors ne hésitez pas à regarder à travers les révisions pour voir des informations générales sur l'histoire et les choses essayé.


J'utilise un CompletionService avec un ExecutorService et callable, appeler simultanément le un certain nombre de fonctions sur quelques webservices différentes par le code généré CXF .. Ces services contribuent différentes informations vers un ensemble unique d'informations I » m à l'aide pour mon projet. Les services peuvent cependant ne pas répondre pendant une période de temps prolongée sans lancer une exception, prolongeant l'attente de l'ensemble combiné d'informations.

Pour contrer cela, je suis en cours d'exécution tous les appels de service en même temps, et après quelques minutes voudrais mettre fin à l'un des appels qui n'ont pas encore terminé, et connectez-vous de préférence ceux qui ont été pas encore fait soit à l'intérieur du appelable ou en lançant une exception détaillée.

Voici un code très simplifié pour illustrer ce que je fais dé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;
        }
    };
}

Et le code qui commence simultanément l'appelle 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;
    }
}

Le problème que je vais avoir avec ce code est que les appelables ne sont pas réellement annulées en attendant port.getXXXFeatures (...) pour revenir, mais en quelque sorte continuent de fonctionner. Comme vous pouvez le voir dans les déclarations de if (Thread.currentThread().isInterrupted()) log.error("XXX was interrupted"); le drapeau interrompu set après le retour de port.getFeatures, ce n'est disponible après l'appel Webservice se termine normalement, au lieu de l'avoir été interrompu quand j'ai appelé Annuler.

Quelqu'un peut-il me dire ce que je fais mal et comment je peux arrêter la course CXF appel Webservice après une période de temps donnée, et enregistrer ces informations dans ma demande?

Cordialement, Tim

Était-ce utile?

La solution

Modifier 3 Nouvelle réponse.

Je vois ces options:

  • Publier votre problème sur le CXF Apache demande de fonctionnalité
  • Fix ACXF vous et d'exposer certaines fonctionnalités.
  • Recherchez les options de soutien d'appel asynchrone WS au sein de l'Apache CXF
  • envisager de passer à un autre fournisseur de WS (JAX-WS?)
  • Faites votre WS-vous appeler à l'aide API RESTful si le service supporte (par exemple la requête HTTP simple avec des paramètres)
  • Pour les experts über seulement:. Utiliser vrai fils / groupe de threads et de tuer les fils avec des méthodes peu orthodoxes

Autres conseils

Les CXF docs ont des instructions pour configurer le délai d'attente de lecture sur le HttpURLConnection: http://cwiki.apache.org/CXF20DOC/ client-http-transport-notamment-ssl-support.html

Ce serait probablement répondre à vos besoins. Si le serveur ne répond pas dans le temps, une exception est levée et la appelable obtiendrait l'exception. (Sauf qu'il ya un bug qui est peut se bloquer à la place. Je ne sais plus si cela a été fixé pour 2.2.2 ou si elle est juste dans les SNAPSHOTS en ce moment.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top