• Aucun résultat trouvé

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 }

Documents relatifs