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) :
  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.
  2. 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) :
  1. Le producteur commence d'abord par créer un objet de type Producer et un objet de type Producer_Synchronizer.
  2. Le consommateur commence d'abord par créer un objet de type Consumer et un objet de type Consumer_Synchronizer.
  3. 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.
  4. 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).
  5. 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 :
  1. Création des objets CORBA.
  2. 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().
  3. Enregistrement auprès du contrôleur grâce à Register_Consumer ou Register_Producer.
  4. 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().
  5. 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 :

  1. 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 ).
  2. 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.