Olivier Lemer
Étant donné un groupe de processus.
Chacun a une aptitude, pas nécessairement statique.
On veut élire celui qui a la meilleure aptitude.
Par exemple :
Propriétés souhaitées
Mutex
Élection
Essaie d'être équitable
Partage l'accès à une section
Tout demandeur sera accepté
Bloquant si SC est prise
Choisit la meilleure aptitude
Partage le droit au titre d'élu
Un demandeur peut ne jamais être élu
Non-bloquant si un autre est élu
Là où la Mutex assure que tout le monde aura droit à son moment,
l'élection sert uniquement à décider à qui attribuer un titre spécial d'élu.
Pour l'instant, on supposera
a.k.a. un algorithme naïf
Idée
"tout le monde doit tout savoir"
J'envoie mon aptitude à tout le monde.
Je reçois l'aptitude de tout le monde.
Le plus fort gagne.
Une élection commence
Deux événements
Je broadcast mon aptitude.
J'attends 2T pour tout recevoir.
Je détermine l'élu.
Réception d'une aptitude
Si je ne suis pas déjà en élection,
j'entre en élection.
Si une élection est en cours quand une nouvelle est demandée, elle est différée à la fin de celle en cours.
Exemple
B
A
3
apt=15
apt=3
C
apt=9
3
A
B
C
3
Entrée en élection
9
A
B
C
3
9
Entrée en élection
15
A
B
C
3
15
A
B
C
3
9
A
B
C
3
9
15
A
B
C
3
9
15
A
B
C
3
9
15
A est élu !
A est élu !
A est élu !
Problème ?
Problème
B
A
apt=15
apt=3
C
apt=9
Entrée en élection
Entrée en élection
3
3
A
B
C
3
9
A
B
C
3
9
A
B
C
3
9
A
B
C
3
9
15
A
B
C
3
9
15
A
B
C
3
9
15
15
A
B
C
3
15
B est élu !
A est élu !
A est élu !
17
17
Nouvelle
aptitude : 17
A
B
C
17
9
15
Solution : Attendre au moins 1T avant toute nouvelle élection.
Performance
Communication
O(N^2) messages par élection
Durée d'une élection
Jusqu'à 4T
(1T d'attente, 2T de timeout, 1T de transit)
Pseudocode
Variables
self
entier, constant
mon numéro de processus
inElection
booléen, init false
ssi une élection est en cours
apt_self
entier
mon aptitude
n
entier, constant
nombre de processus
apts
tableau d'entiers
aptitudes de tous les processus
T
entier, constant
durée maximale d'une transmission
isReqPending
booléen, init false
ssi une élection est en attente
élu
entier
id du processus élu
Écouter infiniment les événements suivants :
Demande d'élection par la couche applicative
Demande d'obtention de l'élu par la couche applicative
Demande de changement d'aptitude à new_apt
Réception de l'aptitude apt_i de i
Timeout
Note : les traitements de ces événements sont faits de manière séquentielle.
Initialisation
Demande de changement d'aptitude à new_apt
apt_self ← new_apt
Attendre pendant 1T
Démarrer une élection
Demande d'obtention de l'élu par la couche applicative
Retourner elu
Demande d'élection de la couche applicative
Attendre pendant 1T
Démarrer une élection
Démarrer une élection
Si inElection
isReqPending ← true
Sinon
inElection ← true
apts[j] ← -inf pour tout j
apts[self] ← apt_self
Envoi de apt_self à tous les autres processus
Lancer un timer de 2T
Réception de l'aptitude apt_i de i
Si pas inElection
Démarrer une élection
apts[i] ← apt_i
Timeout
élu ← i tel que apts[i] est le premier maximum de apts.
inElection ← false
Si isReqPending
isReqPending ← false
Attendre pendant 1T
Démarrer une élection
Pseudocode++ (avec deux routines)
Diffuseur
Collecteur
Permet de tirer profit de la concurrence.
Responsable de déclencher les élections et communiquer avec l'application.
Responsable de collecter les aptitudes.
Variables partagées
self
entier, constant
mon numéro de processus
n
entier, constant
nombre de processus
T
entier, constant
durée maximale d'une transmission
Routine 1 - Diffuseur
Écouter infiniment les événements suivants :
Demande d'entrée en élection
Demande de changement d'aptitude à new_apt
Demande de l'élu par la couche applicative
Initialisation
Variables de la routine 1
élu
entier
id du processus élu
apts
tableau d'entiers
aptitudes de tous les processus
apt_self
entier, constant
mon aptitude
apt_self ← new_apt
Exécuter entrer en élection
Demande de changement d'aptitude à new_apt
Demande d'entrée en élection
Routine 1 - Diffuseur
Demande de l'élu par la couche applicative
Exécuter entrer en élection
Retourner elu
Attente bloquante durant 1T
Envoi de apt_self à tous les autres processus
Envoi de apt_self à la routine Collecteur
Attente bloquante durant 2T
Obtention de apts de la routine Collecteur
élu ← i tel que apts[i] est le premier maximum de apts
Entrer en élection
Routine 1 - Diffuseur
Boucle sur l'attente de réception de apt_i de la part de i
Initialisation
apts ← Tableau de taille n initialisé à -inf
apts[i] ← apt_i
Si i != self
Demander une élection à Diffuseur
Boucle sur l'attente de
Réception de apt_i de i
apts[i] ← apt_i
Demande de apts par Diffuseur
Retourner apts
Sortir de cette boucle
Routine 2 - Collecteur
En cas de panne ?
Un processus ne tombe jamais en panne pendant l'envoi de messages en batch.
Seul danger : Pendant une élection qu'il allait gagner.
On suppose alors un détecteur de panne chez les autres, surveillant l'élu :
Si je détecte une panne de l'élu, je demande une nouvelle élection.
Supposition
Soit il envoie tout, soit il n'envoie rien.
Gestion de telles pannes
Détecteur parfait ou un jour ?
Un jour suffit : si suspicion annulée, relancer une élection.
(Il existe des protocoles de communication qui garantissent cela)
En cas de faux positif, le même élu sera à nouveau choisit.
Exercice
On suppose :
Trois processus
A, avec aptitude initiale de 15B, avec aptitude initiale de 15C, avec aptitude initiale de 20
Les événements suivants ont lieu
T=1 : A demande une électionT=2 : l'aptitude de B devient 25T=2 : B demande une électionT=5 : l'aptitude de C devient 10T=5 : C demande une électionT=7 : B tombe en panneExercice - Solution