Commit 81f7c618 authored by 's avatar
Browse files

quelques simplifications dans le code, et l'intro du rapport est faite. Mais...

quelques simplifications dans le code, et l'intro du rapport est faite. Mais le latex comile plus, pour une raison obscure...
parent e5c26d12
......@@ -141,13 +141,13 @@ class LamportClient(threading.Thread):
request access to critical section
"""
mtime = time.time()
self.queue.append((self.id, mtime))
self.add_to_queue(self.id, mtime)
message = "{},R,{}".format(self.id, mtime)
self.publish(message)
print("{} requesting at time {}".format(self.id, mtime))
print("queue is now {}".format(self.queue))
def free(self):
self.queue.pop(0)
message = "{},F,{}".format(self.id, time.time())
......@@ -160,16 +160,18 @@ class LamportClient(threading.Thread):
print("{} validating".format(self.id))
def when_requested(self, sender, time):
self.queue.append((sender, time))
self.add_to_queue(sender, time)
print("received request from {} from time = {}".format(sender, time))
self.queue.sort(key = operator.itemgetter(1))
print("queue is now {}".format(self.queue))
self.validate()
def when_freed(self, sender, time):
for (previousSender, previousTime) in self.queue:
if (previousSender == sender):
self.queue.remove((previousSender, previousTime))
#for (previousTime, previousSender) in self.queue:
# if (previousSender == sender):
# self.queue.remove((previousTime, previousSender))
self.queue.pop(0) #if all went right, the request should be the first
#if not, the problem won't be solved by erasing the right one anyway
print("received release notification from {} from time = {}".format(
sender, time))
......@@ -201,12 +203,12 @@ class LamportClient(threading.Thread):
if len(self.queue) > 0:
priority_demand = self.queue[0]
print("next is {}".format(priority_demand))
if(priority_demand[0]) == self.id:
if(priority_demand[1]) == self.id:
print("I am next... can I go?")
can = True
print("I received messages at times {}".format(self.times))
for time in self.times.values():
if (time <= priority_demand[1]):
if (time <= priority_demand[0]):
can = False
return can
else:
......@@ -224,6 +226,16 @@ class LamportClient(threading.Thread):
def ready(self):
return self.isready
def add_to_queue(self, sender, message_time):
self.queue.append((message_time, sender))
self.queue.sort()
def sorting_operator(self, message_queue_item):
sender = message_queue_item[0]
timing = message_queue_item[1]
def critical_section(client):
print("{} in critical section...".format(client.id))
......
......@@ -39,15 +39,15 @@
\newlabel{algoResourceRelease}{{2}{4}{Libération de la ressource}{algorithm.2}{}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.1.2}\IeC {\'E}v\IeC {\'e}nements reconnus par les sites}{4}{subsubsection.2.1.2}}
\newlabel{sec:evenements}{{2.1.2}{4}{Événements reconnus par les sites}{subsubsection.2.1.2}{}}
\@writefile{toc}{\contentsline {paragraph}{\numberline {2.1.2.1}R\IeC {\'e}ception d'un message \texttt {REQ}}{4}{paragraph.2.1.2.1}}
\@writefile{loa}{\contentsline {algorithm}{\numberline {3}{\ignorespaces R\IeC {\'e}ception d'un message \texttt {REQ} par le site $i$ envoy\IeC {\'e} par le site $j$ accompagn\IeC {\'e} de la date $H$}}{5}{algorithm.3}}
\@writefile{toc}{\contentsline {paragraph}{\numberline {2.1.2.1}R\IeC {\'e}ception d'un message \texttt {REQ}}{5}{paragraph.2.1.2.1}}
\@writefile{loa}{\contentsline {algorithm}{\numberline {3}{\ignorespaces R\IeC {\'e}ception d'un message \texttt {REQ} par le site $i$ envoy\IeC {\'e} par le site $j$ accompagn\IeC {\'e} de la date $T_m$}}{5}{algorithm.3}}
\newlabel{algoOnReq}{{3}{5}{Réception d'un message \texttt {REQ}}{algorithm.3}{}}
\@writefile{toc}{\contentsline {paragraph}{\numberline {2.1.2.2}R\IeC {\'e}ception d'un message \texttt {REL}}{5}{paragraph.2.1.2.2}}
\@writefile{loa}{\contentsline {algorithm}{\numberline {4}{\ignorespaces R\IeC {\'e}ception d'un message \texttt {REL} par le site $i$ envoy\IeC {\'e} par le site $j$ accompagn\IeC {\'e} de la date $H$}}{5}{algorithm.4}}
\newlabel{algoOnRel}{{4}{5}{Réception d'un message \texttt {REL}}{algorithm.4}{}}
\@writefile{toc}{\contentsline {paragraph}{\numberline {2.1.2.3}R\IeC {\'e}ception d'un message \texttt {ACK}}{5}{paragraph.2.1.2.3}}
\@writefile{loa}{\contentsline {algorithm}{\numberline {5}{\ignorespaces R\IeC {\'e}ception d'un message \texttt {ACK} par le site $i$ envoy\IeC {\'e} par le site $j$ accompagn\IeC {\'e} de la date $H$}}{5}{algorithm.5}}
\newlabel{algoOnAck}{{5}{5}{Réception d'un message \texttt {ACK}}{algorithm.5}{}}
\@writefile{toc}{\contentsline {paragraph}{\numberline {2.1.2.2}R\IeC {\'e}ception d'un message \texttt {FRE}}{5}{paragraph.2.1.2.2}}
\@writefile{loa}{\contentsline {algorithm}{\numberline {4}{\ignorespaces R\IeC {\'e}ception d'un message \texttt {FRE,j} par le site $i$ envoy\IeC {\'e} par le site $j$ accompagn\IeC {\'e} de la date $T_m$}}{5}{algorithm.4}}
\newlabel{algoOnRel}{{4}{5}{Réception d'un message \texttt {FRE}}{algorithm.4}{}}
\@writefile{toc}{\contentsline {paragraph}{\numberline {2.1.2.3}R\IeC {\'e}ception d'un message \texttt {VAL}}{5}{paragraph.2.1.2.3}}
\@writefile{loa}{\contentsline {algorithm}{\numberline {5}{\ignorespaces R\IeC {\'e}ception d'un message \texttt {VAL} par le site $i$ envoy\IeC {\'e} par le site $j$ accompagn\IeC {\'e} de la date $T_m$}}{5}{algorithm.5}}
\newlabel{algoOnAck}{{5}{5}{Réception d'un message \texttt {VAL}}{algorithm.5}{}}
\@writefile{toc}{\contentsline {section}{\numberline {3}Impl\IeC {\'e}mentation avec RabbitMQ}{6}{section.3}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Impl\IeC {\'e}mentation par le m\IeC {\'e}canisme d'exchange}{6}{subsection.3.1}}
\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.1}Connexion au serveur RabbitMQ et communication avec les voisins}{6}{subsubsection.3.1.1}}
......
This diff is collapsed.
......@@ -6,8 +6,8 @@
\BOOKMARK [5][-]{paragraph.2.1.1.2}{Lib\351ration de la ressource}{paragraph.2.1.1.1}% 6
\BOOKMARK [3][-]{subsubsection.2.1.2}{\311v\351nements reconnus par les sites}{subsection.2.1}% 7
\BOOKMARK [4][-]{paragraph.2.1.2.1}{R\351ception d'un message REQ}{subsubsection.2.1.2}% 8
\BOOKMARK [5][-]{paragraph.2.1.2.2}{R\351ception d'un message REL}{paragraph.2.1.2.1}% 9
\BOOKMARK [5][-]{paragraph.2.1.2.3}{R\351ception d'un message ACK}{paragraph.2.1.2.1}% 10
\BOOKMARK [5][-]{paragraph.2.1.2.2}{R\351ception d'un message FRE}{paragraph.2.1.2.1}% 9
\BOOKMARK [5][-]{paragraph.2.1.2.3}{R\351ception d'un message VAL}{paragraph.2.1.2.1}% 10
\BOOKMARK [1][-]{section.3}{Impl\351mentation avec RabbitMQ}{}% 11
\BOOKMARK [2][-]{subsection.3.1}{Impl\351mentation par le m\351canisme d'exchange}{section.3}% 12
\BOOKMARK [3][-]{subsubsection.3.1.1}{Connexion au serveur RabbitMQ et communication avec les voisins}{subsection.3.1}% 13
......
No preview for this file type
......@@ -51,7 +51,7 @@ Ces deux propriétés sont fondamentales, l'une pour l'intégrité du système,
Un algorithme d'exclusion mutuelle a donc pou but d'assurer ces propriétés.
\newline
Nous pouvons envisager deu manières d'implémenter un tel algorithme : de manière centralisée, ou de manière distribuée.
Nous pouvons envisager deux manières d'implémenter un tel algorithme : de manière centralisée, ou de manière distribuée.
Un algorithme centralisé aura une entité responsable de l'organisation des accès à la ressource. Si cette entité vient à dysfonctionner, le système entier est en danger.
Un algorithme centralisé répartira la tâche sur le système entier, afin de se passer du coordinateur, en assurant une auto-organisation des différents éléments entre eux.
\newline
......@@ -81,13 +81,14 @@ Chaque processus possède un entier appelé estampille. Il est mis à jour selon
Ci-dessous est présentée la structure algorithmique du système :
Chaque site possède les attributs suivant :
Chaque site a accès aux les attributs suivant :
\vspace{\baselineskip}
\begin{itemize}
\item $Voisins$ : Ensemble des identifiants de tous les autres sites ;
\item $T_i$ : Estampille de $i$;
\item $Times$ : Structure indiquant pour chaque site l'estampille accompagnant le dernier message envoyé.
\item $T$ : Temps système;
\item $Times$ : Structure indiquant pour chaque site le timing associé au dernier message reçu.
\item $Queue$ : Structure constituée de la liste de toutes les demandes d'accès à la ressource en attente
\end{itemize}
\subsubsection{Actions initiées par les sites}
......@@ -95,21 +96,25 @@ Chaque site possède les attributs suivant :
\paragraph{Acquisition de la ressource}
Lorsque le site \texttt{i} souhaite acquérir la ressource, il le signale aux autres sites en diffusant un message \texttt{REQ}, accompagné de son instant d'émission texttt{ti}.
Il attend ensuite la réponse des autres sites, sous la forme de messages \texttt{VAL} accompagnés des instants correspondants.
Lorsque le nœud sait que sa requête est la plus ancienne, c'est-à-dire une fois que tous les autres sites lui ont fait parvenir un message ultérieur à sa requête, il s'empare de la ressource.
Il entre alors dans la section critique.
Il ajoute alors sa demande dans sa $Queue$.
Le noeud acquière la ressource lorsqu'il sait que sa requête est la plus ancienne, c'est-à-dire qu'elle répond aux deux propriétés suivantes :
\vspace{\baselineskip}
\begin{itemize}
\item la requête est la plus ancienne dans $Queue$;
\item tous les autres sites lui ont fait parvenir un message ultérieur à sa requête, ce qui se caractérise par des temps enregistrés dans $Times$ plus élevés que celui de la demande; (ce qui assure la fiabilité de $Queue$)
\end{itemize}
\begin{algorithm}[H]
\caption{Acquisition de la ressource par le site $i$}\label{algoResourceAcquisition}
\begin{algorithmic}[1]
\Procedure{Acquisition de la ressource}{}
\State $H_i += 1$
\State $T_ir = T_i$
\For{$j \in Voisins$}
\State $Envoyer$ $(REQ, H_i)$ $au$ $site$ $j$
\State $Envoyer$ $(REQ, T_ir)$ $au$ $site$ $j$
\EndFor
\State $Messages[i] = REQ$
\State $Horloges[i] = H_i$
\While{$\neg (\forall j \in Voisins, (Horloges[i] < Horloges[j] \lor (Horloges[i] = Horloges[j] \land i < j)))$}
\State $Times_i[i] = T_ir$
\While{$\neg (\forall j \in Voisins, (T_ir < Times_i[j] \lor (T_ir = Times_i[j] \land i < j)))$}
\State $Attendre$
\EndWhile
\State $Acquerir$ $la$ $ressource$
......@@ -120,18 +125,17 @@ Il entre alors dans la section critique.
\paragraph{Libération de la ressource}
Une fois la section critique achevée, le site libère la ressource, et le signale aux autres sites.
Il diffuse alors un message \texttt{REL}, accompagné de son horloge logique.
Il diffuse alors un message \texttt{FRE}, accompagné de son timing.
\begin{algorithm}[H]
\caption{Libération de la ressource par le site $i$}\label{algoResourceRelease}
\begin{algorithmic}[1]
\Procedure{Libération de la ressource}{}
\State $H_i += 1$
\State $T_if = T_i$
\For{$j \in Voisins$}
\State $Envoyer$ $(REL, H_i)$ $au$ $site$ $j$
\State $Envoyer$ $(FRE, T_if)$ $au$ $site$ $j$
\EndFor
\State $Messages[i] = REL$
\State $Horloges[i] = H_i$
\State $Times_i[i] = T_if$
\EndProcedure
\end{algorithmic}
\end{algorithm}
......@@ -140,53 +144,46 @@ Il diffuse alors un message \texttt{REL}, accompagné de son horloge logique.
\label{sec:evenements}
Lors de la réception d'un message, chaque site déclenche des opérations, correspondant à la nature du message reçu.
En particulier, l'horloge logique locale est synchronisée à chaque fois qu'un message est reçu, et le type de message est enregistré dans le tableau $Messages$.
En particulier, le temps associé au message (soit le temps de son départ) est enregistré dans $Times_i[j]$, où $j$ est l'émetteur et $i$ le récepteur.
\paragraph{Réception d'un message \texttt{REQ}}
Lorsque le site reçoit un message \texttt{REQ}i du site $j$, il synchronise son horloge logique avec celle reçue, et envoie un message \texttt{ACK} au site $j$.
Lorsque le site reçoit un message \texttt{REQ}i du site $j$, il envoie un message \texttt{VAL}, accompagné de son timing au site $j$.
\begin{algorithm}[H]
\caption{Réception d'un message \texttt{REQ} par le site $i$ envoyé par le site $j$ accompagné de la date $H$}\label{algoOnReq}
\caption{Réception d'un message \texttt{REQ} par le site $i$ envoyé par le site $j$ accompagné de la date $T_m$}\label{algoOnReq}
\begin{algorithmic}[1]
\Procedure{Réception d'un message \texttt{REQ(H)}}{}
\State $H_i = max(H_i, H) + 1$
\State $Messages[j] = REQ$
\State $Horloges[j] = H$
\State $Envoyer$ $(ACK, H_i)$ $au$ $site$ $j$
\Procedure{Réception d'un message \texttt{REQ(T_m,j)}}{}
\State $Queue.append(REQ(T_m,j))$
\State $Times_i[j] = T_m$
\State $Envoyer$ $(ACK, T_i)$ $au$ $site$ $j$
\EndProcedure
\end{algorithmic}
\end{algorithm}
\paragraph{Réception d'un message \texttt{REL}}
\paragraph{Réception d'un message \texttt{FRE}}
Lorsque le site $i$ reçoit un message \texttt{REL} du site $j$, il synchronise son horloge logique, et associe l'état \texttt{REL} au site $j$.
Lorsque le site $i$ reçoit un message \texttt{FRE} du site $j$, il synchronise son horloge logique, et associe l'état \texttt{FRE} au site $j$.
\begin{algorithm}[H]
\caption{Réception d'un message \texttt{REL} par le site $i$ envoyé par le site $j$ accompagné de la date $H$}\label{algoOnRel}
\caption{Réception d'un message \texttt{FRE,j} par le site $i$ envoyé par le site $j$ accompagné de la date $T_m$}\label{algoOnRel}
\begin{algorithmic}[1]
\Procedure{Réception d'un message \texttt{REL(H)}}{}
\State $H_i = max(H_i, H) + 1$
\State $Messages[j] = REL$
\State $Horloges[j] = H$
\Procedure{Réception d'un message \texttt{FRE(T_m, j)}}{}
\State $Queue.remove_first()$
\State $Times_i[j] = T_m$
\EndProcedure
\end{algorithmic}
\end{algorithm}
\paragraph{Réception d'un message \texttt{ACK}}
\paragraph{Réception d'un message \texttt{VAL}}
Lorsque le site $i$ reçoit un message \texttt{REL} émis par le site $j$, il synchronise son horloge logique locale.
Puis, si le site $j$ n'est pas dans l'état \texttt{REQ}, le site $i$ lui associe l'état \texttt{ACK}.
Lorsque le site $i$ reçoit un message \texttt{FRE} émis par le site $j$ à $T_m$, il le prend en compte dans sa table de temporalité, s'assurant avoir reçu un message tous les messages avant $T_m$ de la part de $j$, ce qui lui permettra de savoir que $j$ n'a pas envoyée de requête inconnue plus ancienne que $T_m$ (on suppose en effet que le canal de communication est FIFO et sans perte de messages)
\begin{algorithm}[H]
\caption{Réception d'un message \texttt{ACK} par le site $i$ envoyé par le site $j$ accompagné de la date $H$}\label{algoOnAck}
\caption{Réception d'un message \texttt{VAL} par le site $i$ envoyé par le site $j$ accompagné de la date $T_m$}\label{algoOnAck}
\begin{algorithmic}[1]
\Procedure{Réception d'un message \texttt{ACK(H)}}{}
\State $H_i = max(H_i, H) + 1$
\If{$Messages[j] \neq REQ$}
\State $Messages[j] = ACK$
\State $Horloges[j] = H$
\EndIf
\Procedure{Réception d'un message \texttt{VAL(T)}}{}
\State $Times[j] = T_m$
\EndProcedure
\end{algorithmic}
\end{algorithm}
......@@ -324,23 +321,23 @@ def request(self):
self.messages[self.index] = 'REQ'
self.clocks[self.index] = self.clock
# Publication d'un message REL
# Publication d'un message FRE
def release(self):
self.clock += 1
msg = "{},REL,{}".format(self.index, self.clock)
msg = "{},FRE,{}".format(self.index, self.clock)
self.publish(msg)
self.messages[self.index] = 'REL'
self.messages[self.index] = 'FRE'
self.clocks[self.index] = self.clock
# Publication d'un message ACK
# Publication d'un message VAL
def acknowledge(self):
msg = "{},ACK,{}".format(self.index, self.clock)
msg = "{},VAL,{}".format(self.index, self.clock)
self.publish(msg)
if self.messages[self.index] != 'REQ':
self.messages[self.index] = 'ACK'
self.messages[self.index] = 'VAL'
\end{imtaCode}
\subsubsection{Réception d'un message}
......@@ -363,9 +360,9 @@ def on_receive(self, ch, method, properties, body):
# Appel du callback adéquat
if message == 'REQ':
self.on_request(sender, clock)
elif message == 'REL':
elif message == 'FRE':
self.on_release(sender, clock)
elif message == 'ACK':
elif message == 'VAL':
self.on_acknowledge(sender, clock)
\end{imtaCode}
......@@ -382,7 +379,7 @@ def on_request(self, sender, clock):
self.messages[sender] = 'REQ'
self.clocks[sender] = clock
# Réponse par un message ACK
# Réponse par un message VAL
self.acknowledge()
# Réception d'un message REL
......@@ -391,10 +388,10 @@ def on_release(self, sender, clock):
self.clock = max(self.clock, clock) + 1
# Enregistrement de l'état et de l'horloge dans les tableaux locaux
self.messages[sender] = 'REL'
self.messages[sender] = 'FRE'
self.clocks[sender] = clock
# Réception d'un message ACK
# Réception d'un message VAL
def on_acknowledge(self, sender, clock):
# Synchronisation de l'horloge
self.clock = max(self.clock, clock) + 1
......@@ -402,7 +399,7 @@ def on_acknowledge(self, sender, clock):
# Enregistrement de l'état et de l'horloge dans les tableaux locaux
# Si l'émetteur du message est dans l'état REQ, ne pas ré-écrire son état
if self.messages[sender] != 'REQ':
self.messages[sender] = 'ACK'
self.messages[sender] = 'VAL'
self.clocks[sender] = clock
\end{imtaCode}
......@@ -490,7 +487,7 @@ def release_resource(self):
self.must_release = True
\end{imtaCode}
Comme pour les messages \texttt{REQ}, le thread du nœud regarde dans son cycle de vie s'il doit émettre un message \texttt{REL}, et le cas échéant, l'émet.
Comme pour les messages \texttt{REQ}, le thread du nœud regarde dans son cycle de vie s'il doit émettre un message \texttt{FRE}, et le cas échéant, l'émet.
\begin{imtaCode}{python}
def run(self):
......
......@@ -6,9 +6,9 @@
\contentsline {paragraph}{\numberline {2.1.1.1}Acquisition de la ressource}{4}{paragraph.2.1.1.1}
\contentsline {paragraph}{\numberline {2.1.1.2}Lib\IeC {\'e}ration de la ressource}{4}{paragraph.2.1.1.2}
\contentsline {subsubsection}{\numberline {2.1.2}\IeC {\'E}v\IeC {\'e}nements reconnus par les sites}{4}{subsubsection.2.1.2}
\contentsline {paragraph}{\numberline {2.1.2.1}R\IeC {\'e}ception d'un message \texttt {REQ}}{4}{paragraph.2.1.2.1}
\contentsline {paragraph}{\numberline {2.1.2.2}R\IeC {\'e}ception d'un message \texttt {REL}}{5}{paragraph.2.1.2.2}
\contentsline {paragraph}{\numberline {2.1.2.3}R\IeC {\'e}ception d'un message \texttt {ACK}}{5}{paragraph.2.1.2.3}
\contentsline {paragraph}{\numberline {2.1.2.1}R\IeC {\'e}ception d'un message \texttt {REQ}}{5}{paragraph.2.1.2.1}
\contentsline {paragraph}{\numberline {2.1.2.2}R\IeC {\'e}ception d'un message \texttt {FRE}}{5}{paragraph.2.1.2.2}
\contentsline {paragraph}{\numberline {2.1.2.3}R\IeC {\'e}ception d'un message \texttt {VAL}}{5}{paragraph.2.1.2.3}
\contentsline {section}{\numberline {3}Impl\IeC {\'e}mentation avec RabbitMQ}{6}{section.3}
\contentsline {subsection}{\numberline {3.1}Impl\IeC {\'e}mentation par le m\IeC {\'e}canisme d'exchange}{6}{subsection.3.1}
\contentsline {subsubsection}{\numberline {3.1.1}Connexion au serveur RabbitMQ et communication avec les voisins}{6}{subsubsection.3.1.1}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment