• Aucun résultat trouvé

3.3 Impacts sur la tolérance aux pannes

4.1.6 Protocole

Nous résumons tout d’abord dans cette section le protocole proposé, puis pro-posons une description précise sous forme de pseudo-code dans la figure 4.9.

4.1.6.1 Synthèse

Comme la réexécution s’effectue depuis un état global incohérent, des pro-blèmes de cohérence peuvent survenir. Nous résumons point par point comment ces différents problèmes sont gérés et résolus :

⇒ Requête orpheline : sa réception est remplacée par une promesse. Le problème de la double réception est donc écarté, et la position de cette ré-ception est conservée durant la réexécution. Le contenu de la requête est assuré d’être le même que dans l’exécution de référence grâce aux histo-riques de réception.

4.1 Protocole par point de reprise pour ASP 71

⇒ Réponse orpheline : la réception du duplicata ne correspond à aucun fu-tur et est donc ignorée. Le problème de la double réception est donc écarté. Le contenu de la réponse est assuré d’être le même que dans l’exécution de référence grâce à l’historique de réception.

⇒ Requête en transit : sa réception est journalisée dans l’historique de ré-ception. Le message est donc reçu durant la réexécution, et sa position par rapport aux autres réceptions est conservée. L’ordonnancement causal est donc assuré, même pour les requêtes en transit.

⇒ Réponse en transit : sa réception est journalisée, et le futur correspon-dant est mis à jour avant la réexécution. Le message est donc reçu durant la réexécution. Le protocole assure que cette réponse ne peut pas être reçue en avance puisque l’envoi de la requête correspondante appartient au point de reprise.

⇒ Réponse en avance : l’attente par nécessité sur les promesses de requête permet d’assurer qu’aucune réponse ne peut être reçue en avance par une activité.

4.1.6.2 Algorithme

La figure 4.9 présente le protocole sous forme de pseudo-code. On notera que : − la procédureInitialisation()est appelée à la création d’une activité, − la procédure TentativePoint() est appelée entre chaque service de

re-quête.

Chaque activité i maintient les valeurs suivantes : − l’index Ni du dernier point de reprise pris, − l’index Nsuiv

i du prochain point de reprise à prendre, − son numéro d’incarnation courant Ii,

− l’index du point de reprise utilisé lors de la dernière reprise, − le compte à rebours T T Ci,

− l’historique de réception de requête Hki associé au point de reprise k, − un journal de réponses Rk

i associé au point de reprise k.

Les valeurs transportées par un message Mi,j, et qui sont donc connues de l’activité réceptrice j sont :

− l’index Ni du dernier point de reprise de i, − l’index Hidu dernier historique fermé par i, − le numéro d’incarnation courant Ii de i,

− l’index LRidu point de reprise utilisé pour la dernière reprise de i. Enfin, nous notons Qrcv

i la queue des requêtes en attente de l’activité i, et ⊕ l’opérateur de concaténation.

•Initialisation() Ii= LRi = Ni= 0 Nsuiv i = 1 T T Ci= T T C_IN IT TentativePoint() •Reception(Mi,j) si (Ii== Ij) alors si (ouvert(HNj j ) et Nj< Hi) alorsfermer(HNj j ) si (Ni< Nj) alors

si (Mi,jest uneQi,j) alors HNj

j ⊕ Qi,j sinonRNj j ⊕ Ri,j sinon si (ouvert(HNj j )) alors Hk i ⊕ Qpmd i,j si (Ni> Nj) alors Nsuiv j = Ni sinon si (Ii> Ij) alors

i bloqué sur l’envoi de Mi,j

Recouvrement(j, Ii, LRi) sinon envoyer Mrec LRj,Ij à i, ignorer Mi,j •Reception(Mgs n ) si (ouvert(HNi i ) et Ni< n) alorsFermer(HNi i ) •Fermer(Hk i)

stocker sur mémoire stable Hk i et Rk i avec Ck i ouvert(Hk i) = faux •TentativePoint() si (Nsuiv i > Ni) alors Point(Nsuiv i ) sinon si (T T Ci == 0) alorsPoint(Ni+ 1) •Point(n) capturer Cn i dans Cn i, ∀Qj,i∈ Qrcv

i , si Nj≥ n alors Qi,jremplacé par Qpmd i,j Ni = n, T T Ci = T T C_IN IT créer Hn i et Rn i ouvert(Hn i) = vrai stocker Cn i en mémoire stable

si état globaln complet alors envoyer à tous Mgs n

•Panne(i)

Iglobal = Iglobal+ 1

Recouvrement(i, Iglobal, n)

envoyer à tous Mrec n,Iglobal

•Reception(Mrec n,k)

si (Ii< k) alorsRecouvrement(i, k, n)sinon ignorerMrec n,k •Recouvrement(i, k, n) Stopper activité Récuperer Cn i et Hn i et Rn i

Modifier l’état de l’activité à partir de Cn i

Qrcv

i ⊕ Hn

i

Ii= k , LRi = n

Mettre à jour les futurs associés aux réponses dans Rn i

Redémarrer activité

4.1 Protocole par point de reprise pour ASP 73

4.1.7 Causalité potentielle

Le protocole que nous proposons ici dans le cadre d’ASP repose implicitement sur une relation de causalité entre les évènements spécifique au modèle ASP (dif-férente de la relation de Lamport). En effet, la notion de cohérence utilisée dans la description du protocole suppose que certains évènements, bien que consécu-tifs sur la même activité, ne sont pas forcément causalement liés. Nous montrons informellement ici comment cette relation est exploitée implicitement, et donc comment la connaissance de cette relation est nécessaire pour pouvoir modéliser et prouver de façon formelle dans le chapitre 5 la recouvrabilité des états globaux formés durant l’exécution.

L’utilisation de promesses de requête pour virtuellement annuler la réception des requêtes orphelines repose sur une causalité locale partielle. En effet, la re-lation de causalité pour ASP définie dans la section 3.1.5 précise que, tant qu’elle n’est pas servie, la réception d’une requête n’est causalement liée qu’aux autres réceptions de requêtes. Le positionnement de la promesse par rapport aux autres réceptions est donc suffisant ; il n’y pas d’autre relation causale à conserver.

C’est la même idée qui permet l’utilisation d’une liste de promesses de requêtes pour réordonner les réceptions de requête en avance de façon transparente, c’est-à-dire sans que l’activité réceptrice intervienne, et sans utiliser un mécanisme de temporisation des messages extérieur à l’activité. Même si l’activité reçoit les requêtes dans un ordre différent et à des moments différents relativement à son exécution de référence, le fait que les promesses de requête puissent être ordon-nées entre elles et par rapport aux autres réceptions de requêtes suffit à assurer la cohérence.

L’attente par nécessité sur la promesse d’une requête orpheline repose elle aussi sur une causalité locale partielle. On autorise en effet la réexécution de l’activité depuis le point de reprise, même si le duplicata de la requête orpheline

n’a pas encore été reçu. De manière plus générale, les branches d’exécution

cau-salement indépendantes de l’évènement qui n’a pas encore eu lieu peuvent être exécutées sans risque d’incohérence. L’activité peut donc servir les requêtes qui ont été reçues avant la ou les requêtes orphelines, et recevoir d’autres requêtes puisque la position de la requête est conservée par la promesse. L’attente par nécessité uniquement sur le service des requêtes orphelines est donc suffisante pour assurer une cohérence minimum de la réexécution, et éviter la réception de réponse en avance.

Dans le cadre de la causalité stricte de Lamport, cette réexécution n’est pas correcte. En effet, des évènements déterministes dont le passé local n’a pas encore eu lieu sont exécutés. Pour assurer la cohérence au sens de Lamport, il faudrait bloquer complètement l’exécution tant que tous les messages orphelins ne sont pas reçus. La connaissance d’une relation de causalité plus précise nous permet ici une synchronisation plus ciblée, et donc plus efficace.

Dans le cas des réponses, la correction du protocole repose sur le fait que le pre-mier évènement qui est une conséquence causale de la réception d’une réponse est le premier accès au futur correspondant. Or, comme on l’a vu dans la section 3.1.5,

cet évènement est particulier dans le modèle ASP : il est (comme le service d’une promesse de requête) gardé par un mécanisme d’attente par nécessité. Cette at-tente par nécessité fait que la réception d’une réponse a toujours lieu avant le premier accès à un futur, et donc que la relation de causalité entre ces deux évè-nements est toujours conservée. Il n’y a donc pas de mécanisme particulier à ajou-ter au protocole pour assurer le maintien des relations de causalité vis-à-vis des réceptions de réponses, comme c’est le cas pour les requêtes.