Communication asynchrone avec CORBA/Java
Frank Singhoff
Correction possible disponible ici
Dans cet exercice on étudie une implémentation possible
du service d'événements de CORBA. Ce service est très souvent
livré en standard avec les bus à objets CORBA et permet aux clients/serveurs
d'échanger des données de façon asynchrone. On parle alors de producteurs
pour ceux qui produisent les données et de consommateurs pour ceux qui
les exploitent.
Dans un répertoire,
récupérez les fichiers suivants :
Makefile,
Impl_is_ready.java,
Synchronized_Bool.java,
Active_Wait.java,
Producer_Impl.java,
Consumer_Impl.java,
et Channel.idl.
Vous les stockerez tous dans un répertoire commun.
Figure 1. Communication producteur/consommateur.
Avec le service d'événements, une communication peut être réalisée selon deux modes différents (cf. Figure 1) :
- Le mode Push : dans ce mode, le consommateur héberge un objet CORBA dont l'interface est de type Consumer (cf. fichier Channel.idl). Le producteur utilise la méthode Push de cette interface pour envoyer au consommateur chaque message produit.
- Le mode Pull : dans ce mode, le producteur héberge un objet CORBA dont l'interface est de type Producer. Le consommateur utilise la méthode Pull de cette interface pour obtenir le dernier message produit.
Figure 2. Séquence de messages échangés entre contrôleur, producteur et consommateur.
On suppose que le service d'événements que l'on souhaite implanter permette
à un producteur et à un consommateur d'utiliser à tout moment l'un ou l'autre
des modes de communication. On souhaite donc que, lorsque ce type d'application
démarre, producteur et consommateur effectuent un rendez-vous afin
de s'échanger une référence d'objet CORBA
Consumer et Producer.
Pour ce faire, on ajoute à notre application un troisième processus (appelé le
contrôleur) ainsi que 3 nouvelles interfaces IDL :
Consumer_Synchronizer,
Producer_Synchronizer et
Channel_Controler.
Le fonctionnement de notre application est alors le suivant (cf. Figure 2) :
- Le producteur commence d'abord par créer un
objet de type Producer et un objet de type Producer_Synchronizer.
- Le consommateur commence d'abord par créer un
objet de type Consumer et un objet de type Consumer_Synchronizer.
- Par la suite, le producteur et le consommateur s'enregistrent auprès
du contrôleur grâce aux méthodes
Register_Producer et Register_Consumer. A cette occasion, le producteur (respectivement
le consommateur) transmet les références sur les deux objets CORBA
de type Producer et Producer_Synchronizer
qu'il a précédemment instanciés (respectivement références de type Consumer et Consumer_Synchronizer).
Bien sûr, cette première phase d'enregistrement ne suppose pas un
ordre prédéterminé d'enregistrement du producteur et du consommateur.
- Lorsque le contrôleur sait que producteur et consommateur sont prêts/enregistrés,
il invoque la méthode Wakeup des objets Consumer_Synchronizer et
Producer_Synchronizer, ce qui a pour effet de réveiller les deux processus en question. A cette occasion, le contrôleur en profite pour
donner au consommateur une référence sur le producteur
(référence d'objet Producer) et pour donner au
producteur une référence sur le consommateur (référence d'objet Consumer).
- A partir de cet instant, producteur et consommateur peuvent échanger
des données dans le mode de leur choix (Pulling ou Pushing)
grâce aux références obtenues à l'étape 4.
Le contrôleur est un serveur CORBA qui implante
l'interface Channel_Controler. Consommateur et
producteur font office à la fois de serveurs et de clients et
fonctionnent comme suit :
- Création des objets CORBA.
- Lancement de la BOA avec la classe Impl_is_ready.java.
Cette classe permet de démarrer la BOA sans bloquer
le thread/serveur qui
instancie cette classe. Ainsi la ligne de code :
new Impl_is_ready(boa).start();
permet de créer une BOA sans bloquer le serveur contrairement
à boa.Impl_Is_Ready().
- Enregistrement auprès du contrôleur grâce à Register_Consumer ou Register_Producer.
- Démarrage du rendez-vous par l'attente du message de synchronisation émis par le contrôleur (invocation de la méthode Wakeup).
Pour ce faire, vous disposez de la classe Active_Wait.java.
La méthode V() permet de réveiller un processus/thread
qui a été mis en attente avec une invocation de la méthode P().
- Enfin, démarrage des communications entre
producteur et consommateur soit en mode Push, soit en mode Pull. Les
messages échangés entre producteurs et consommateurs sont
ici des chaînes de caractères (cf. interfaces
Producer/Consumer).
Vous travaillerez seul ou à deux.
Vous déposerez vos réponses dans un sous répertoire de
~singhoff/CC-SYSDIS-2004.
Le répertoire ~singhoff/CC-SYSDIS-2004 sera fermé après 3h de TP.
Appelez votre sous répertoire
par votre nom
(ou de vos deux noms
si vous travaillez en binome).
Il est fortement conseillé de lire les trois questions avant de commencer.
Question 1 : Implantation du mécanisme de rendez-vous
Implémentez l'application de rendez-vous, c'est à dire :
- Les classes d'implémentation des interfaces de Channel.idl
(les classes
Channel_Controler_Impl.java,
Producer_Synchronizer_Impl.java et
Consumer_Synchronizer_Impl.java ).
- Les classes Java permettant de lancer un producteur, un consommateur et un
contrôleur (respectivement les classes
Producer_Process.java,
Consumer_Process.java et
Controler_Process.java
).
On vous demande d'écrire un producteur et un consommateur
utilisant soit la méthode Push, soit la méthode Pull
(selon votre choix).
Les événements échangés entre producteur et consommateur sont
des chaînes de caractères.
Question 2 : Notion de session
Supposons maintenant que notre application de rendez-vous puisse gérer simultanément
plusieurs rendez-vous de plusieurs couples de producteur-consommateur.
On suppose que le consommateur et le producteur d'un couple donné puisse être
apparenté
par un nom (une chaîne de caractères). Proposez une nouvelle interface IDL permettant
d'offrir cette fonctionnalité. Vous décrirez le fonctionnement de cette nouvelle
implantation.
Toutefois, on ne demande pas ici de donner le code Java
de cette nouvelle implantation .
Question 3 : Arrêter l'application proprement
Lorsque l'on souhaite terminer l'exécution de notre système de rendez-vous, il
est nécessaire de synchroniser les producteurs et consommateurs.
En effet,
dans le mode Push par exemple, si le consommateur
stoppe son fonctionnement sans en avertir le producteur, ce dernier récupérera
une exception lors de l'émission du message suivant.
Proposez une solution pour assurer une terminaison propre de votre programme. Décrivez
les modifications à faire dans votre implémentation
et donnez la
nouvelle version du fichier Channel.idl s'il y a.
Toutefois, on ne vous demande pas ici de donner le code Java de votre
nouvelle implantation.