5.2 Cas d’étude et modèle de fautes
5.3.1 Protocole client-serveur
Dans ce protocole duplex simple, nous ne faisons pas l’hypothèse d’un service de
com-munication de groupe fournissant la diffusion atomique de message. Ainsi le client s’adresse
au serveur primaire et en cas de défaillance de celui-ci s’adresse au serveur secondaire. Nous
faisons donc l’hypothèse que les ports de communication du primaire et du secondaire sont
connus a priori du client. Rappelons aussi que l’on se place dans un système synchrone, à
sa-voir que tout message est reçu dans un intervalle de temps borné en l’absence decrash.
5.3.1.1 Préoccupations transversales coté client
Dans le protocole duplexprimary-backuplorsque le serveur primaire défaille, le serveur
secondaire prend le relais. Le client qui n’a pas reçu de réponse à sa requête la renvoie. Le
se-condaire la reçoit. Le serveur sese-condaire ne doit alors pas exécuter la requête si elle a déjà été
exécutée afin de préserver l’intégrité du système. La requête ne doit être exécutée qu’une seule
fois (only once semantics). Pour ce faire, il est nécessaire d’ajouter un numéro de séquence à la
requête et un identifiant de client. Grâce à ces informations le serveur secondaire sait si pour un
client donné (identifiant client) une requête donnée (numéro de séquence de requête) a déjà
été traitée. Du côté client, il est donc nécessaire d’ajouter aux requêtes ces informations
sup-plémentaires en plus du nom du service demandé. Ces identifiants sont uniques. De la même
manière à la réception de la réponse les informations ajoutées à l’envoie doivent être retirés de
la réponse afin que celle-ci soit traitée. Le client doit également gérer la réception des réponses
et prendre des décisions en ce qui concerne la disponibilité du serveur. En effet lorsque le client
ne reçoit pas de réponse à une requête après un certain délai, le serveur est considéré comme
défaillant. Les requêtes sont alors envoyées au serveur secondaire.
1 V a r i a b l e s du p r o t o c o l e :
2 adresse p r i m a i r e
3 adresse s e c o n d a i r e
4
5 Boucle client {
6 ajouter numero de s e q u e n c e de requete
7 ajouter i d e n t i f i a n t client
8 envoi de la requete au serveur
9 e n r e g i s t r e m e n t de la requete dans le cache
10 a r m e m e n t du m i n u t e u r
11 tant que reponse=null {
12 si ( m i n u t e u r∑ 0) { e x c e p t i o n }
13 si ( m i n u t e u r> 0) { r e c e p t i o n de la reponse
14 si ( reponse6= null ) {
15 arret du minuteur ,
16 retirer numero de s e q u e n c e de reponse
17 }
18 }
19 }
20 t r a i t e m e n t de la reponse
21 }
Listing 5.1 – Algorithme exécuté coté client
Toutes les lignes excepté les lignes 8 et 20 du listing5.5sont des préoccupations
transver-sales. Il convient donc de les encapsuler dans des aspects afin de les séparer des préoccupations
fonctionnelles implémentées par les lignes 8 et 20.
5.3.1.2 Aspects côté client
Les différentes préoccupations transversales identifiées dans le listing5.5peuvent être
en-capsulées dans différents aspects.
Les préoccupations des lignes 7 et 16 sont encapsulées dans un aspect dédié à la gestion de
l’ajout et de la suppression du numéro de séquence de requête. Cet aspect est nommé
ANum-beringcontient deux greffonsinsertetremovedont les rôles sont les suivants :
– ANumbering.insert: ajoute un numéro de séquence à la requête ;
– ANumbering.remove: supprime le numéro de séquence de la réponse ;
Celle de la ligne 7 est encapsulée dans un aspect dédié à la gestion des identifiants de client
(AIdentifier). Cet aspect contient un greffon dont le rôle est le suivant :
– AIdentifier.insert: ce greffon ajoute l’identifiant du client à la requête avant qu’elle ne
soit envoyée.
Un troisième aspect nomméACacheManager.addInencapsule les préoccupations
transver-sales de la ligne 9. Cet aspect contient un greffon nomméACacheManager.addIndont le rôle est
le suivant :
– ACacheManager.addIn: ce greffon est chargé de sauvegarder les requêtes envoyées dans
une structure de données afin de permettre le renvoi des requêtes pour lesquelles aucune
réponse n’a été reçue. Il ajoute dans une structure de données l’identifiant de la requête,
son contenu et un minuteur.
Ce greffon permet le renvoi au serveur secondaire d’une requête pour laquelle il n’y a pas eu
de réponse de la part du serveur primaire pour cause de défaillance. Si l’on se réfère au
com-portement décrit par les lignes 11 à 19 lors de l’attente de la réponse à une requête, le client
vérifie que le temps d’attente imparti pour une requête n’est pas dépassé par le biais du
mi-nuteur affecté à la requête ; si ce denier est dépassé une exception est soulevée. Le client passe
alors au traitement de la requête suivante dans sa liste de requêtes à traiter. Or il faut renvoyer la
requête pour laquelle aucune réponse n’a été reçue du serveur primaire au serveur secondaire.
Ce greffon et la structure de données utilisée contribuent à réaliser ce comportement.
Le renvoi de la requête est géré par un aspect nomméARequestResend. Il encapsule cette
préoccupation transversale. Cet aspect contient un greffon nomméARequestResend.reloaddont
le rôle est le suivant :
– ARequestResend.reload: est chargé de recharger en tête de liste des requêtes à envoyer la
requête envoyée pour laquelle qui n’a pas reçu de réponse.
L’expression de coupe deARequestResendcapture la levée de l’exception liée au dépassement
du temps imparti par le minuteur. Le comportement du greffonARequestResend.reloadest
décrit dans le listing5.2.
Le greffonACacheManager.addIndétaillé ci-dessus ajoute dans une structure de données
les informations liées à une requête et un objet minuteur. Le minuteur fournit une interface
proposant deux opérations :
– start()le minuteur commence le décompte à partir de la valeur avec laquelle il a été
ini-tialisé ;
– stop()le décompte du minuteur est arrêté.
Un quatrième aspect (ATimer) est donc dédié la gestion de ce minuteur. Il qui contient deux
greffonsstartetstop. Il encapsule les préoccupations des lignes 10 et 16. Les rôles respectifs de
ces greffons sont les suivants :
– ATimer.start: appelle l’interfacestart()du minuteur référencé dans la structure de
don-nées, qui décompte un certain temps au bout duquel la réponse liée à une requête
en-voyée au primaire doit être reçue.
– ATimer.stop: arrête le minuteur lorsqu’une réponse pour une requête donnée est reçue.
Ces différents aspects sont appliqués autour de deux points de jonction, les méthodessend()
etreceive(). Chaque aspect effectue une action permettant de composer le comportement
at-tendu du client dans le protocole de réplication duplex. Nous reviendrons plus en détail sur la
composition de ces aspects dans la section5.4.
1 e x c e p t i o n {
2 r e c u p e r a t i o n de la requete dans le cache
3 c h a n g e m e n t d adresse serveur
4 retour a la boucle client
5 }