2010-02-05 2 views
5

J'essaie de comprendre quelles garanties sont fournies pour les événements de service. La spécification OSGi indique que ServiceEvents est synchrone, j'ai supposé qu'un ServiceListener ne recevrait pas d'appel de serviceChanged() avec un événement ServiceEntretien jusqu'à ce que l'appel de serviceChanged() avec un ServiceEvent enregistré soit terminé. Est-ce correct?Quelles garanties de commande sont fournies sur les appels ServiceListener et ServiceTracker?

J'ai aussi eu un coup d'oeil à la source pour ServiceTracker. Il semble essayer de faire face à la situation où ces deux appels serviceChanged() se chevauchent. Est-ce possible?

Y a-t-il des garanties similaires sur les appels à un ServiceTrackerCustomizer?

Répondre

1

C'est une question très délicate. Lorsqu'un service est enregistré dans OSGi, l'événement est géré et toutes les parties intéressantes sont notifiées (auditeurs de service, suivis de service et exécution de service déclarative). Chaque partie intéressée a une chance de gérer l'événement. La gestion de l'événement peut inclure l'enregistrement ou la désinscription de services supplémentaires. En raison du comportement synchrone de la notification ServiceEvent, ces événements sont ensuite envoyés aux parties intéressées. Dans une longue chaîne de dépendance, vous vous retrouvez avec un arbre de notification, où vous allez enregistrer un seul service et cela entraîne l'enregistrement de tout un tas de nouveaux types. Je sais cela parce que cela peut rendre la mise au point des performances OSGi un exercice très difficile, puisque votre appel de service de registre simple a été facturé pour l'activation du service d'un nombre inconnu de services.

Pour répondre précisément à votre question, ce ne est pas une préoccupation multi-thread avec les événements, son un rentrante. C'est le gars qui traite votre événement de registre qui pourrait vous revenir avec une autre notification d'événement avant que l'arbre complet ne soit traité. C'est l'une des raisons pour lesquelles ils recommandent fortement que vous n'inscriviez ou ne désinscriviez jamais de services tout en conservant des verrous, sinon vous pourriez bloquer le thread du distributeur d'événements. Un autre bon moyen de rester en sécurité est d'avoir une arborescence de dépendance de bundle, pas un graphique. Les dépendances circulaires entre les bundles, même si les classes compilent peuvent causer de vrais problèmes.

J'espère que cela aide. Si vous voulez en savoir plus sur ce genre de chose, il y a un nouveau livre sur OSGi et Equinox. Son disponible sur les coupes brutes maintenant et devrait être disponible dans l'impression très bientôt. http://my.safaribooksonline.com/9780321561510

+0

Pour éviter ces tempêtes d'événements lors du démarrage et de garder un peu d'ordre dans lequel vous pouvez utiliser startlevels. – akr

+1

Si le service A est enregistré, chaque ServiceListener intéressé recevra un appel serviceChanged() avec un événement ENREGISTRÉ pour ce service. Est-il possible d'obtenir un nouvel appel serviceChanged() avec un événement UNREGISTERING pour ce même service A * pendant le traitement de l'événement REGISTERED? Je ne peux pas voir que d'être possible que vous avez besoin d'un ServiceRegistration pour supprimer le service et qui est disponible qu'après l'enregistrement est terminé, mais ... –

Questions connexes