From 8a42591baafe40aa3e118e7f612454f19731cb9c Mon Sep 17 00:00:00 2001
From: Robin Leber <51661454+LeberCode@users.noreply.github.com>
Date: Thu, 1 Feb 2024 08:52:16 +0100
Subject: [PATCH] Rafael Heartbeat

---
 __pycache__/voting.cpython-311.pyc | Bin 0 -> 1541 bytes
 client.py                          |   1 -
 server.py                          |  42 +++++++++++++++++++++++------
 3 files changed, 34 insertions(+), 9 deletions(-)
 create mode 100644 __pycache__/voting.cpython-311.pyc

diff --git a/__pycache__/voting.cpython-311.pyc b/__pycache__/voting.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1cb1d5643b195e4afeb653d927acc31a9e23d574
GIT binary patch
literal 1541
zcmb_b&1(}u6rb7Mq>XJFZS&#QYE#5Qifyz8u~-VCAjR4bt0)BtZDt$SCc9yFtF~+*
zhaNn5P*7S$F&Aq~6?)YFz~iRuAuI@jr``g+NH6+kvk6V{<Kpbjo0<1Lzj^Py-+u_f
zz&}4rAs(Uc>`)z?yV>o4%?cuj;0&5Vgj+^an0Sb=jHft)CsEA1!&FC8*tKAb024f-
z-Ekl*NZ%(Tco`Y!3R(lnCd|rM1C7m^))HoM417>)i8DBe$kzw+fQvSmyXS$dpftF@
z8(zZugWj*XHgJ8YXWWy>B-%hR&h~0*YEIH^pR7oFa#~jvU~+wDY;RV|&PY^am_(y{
z{qb8GoZ?iSk(G=Dl6YFy<77taC0cKqs`I(Cy$`kiMErrO%SyU0x3G6;Fe7VvO3mhm
z7LU)WG@GPMGMG_Q(;00DHdQf$PCE%CkId+J<^MGME^Kw3-RdrO4Om?RHU2KBp*rCI
z0~VC|h;h^li;IP#tJA<~WE??JiR3~-S^dx^Apf`&b6LGqXvB2>t>BAUE8Jbsi{aB&
z_;iH{ls1EM472B;x<q2U-QePHw^mq5z<ru7I1t(`E>F%mXN{FzG#YhMvwbzFX%P5K
zrVRkeqpxCT1;#H8uok1^7Ep1*5+_U{T&m<aa1GKahDNN=NPe``B$|TgBxeg5X;x1$
zZ`DyN_#ePofzmb514KgxDpWP<)`L~3V1k!;gC}^-@k;L)9O34iCZsXo^NV1w?~7=l
z`Z{)X8x2GRu@-9*dZB7v$K{FOS{yb0>K7uzBiGqhJRaZ@1dZt#-T4WFh9H3*)^e2H
z0J_K{D@1x^^BGBr3AVs$-wveaDU}pG$qFhd=WHL5sg%-XRk2&^Wz1M(5W~Z|FY8Z3
zk1CR!zBi+SpH2|^U~20?@~Cv->X(FhVayb7uLj??ziKax6~%-lCQSHm-DXeRAg<on
zZs;tdW>2ux6kPRgH=QUWpD$4gbQLZY1E)T=t>4@bKZx6b{xahIiBja)>ZRuopSFC9
z95XxmwvH4#`mM-0^YFQEU@@^B=&q{0xm*xl4!<5=$1ks2kskAK&u>iH9_wzUJ8;E#
zr{SD3b#CLdp`+oH@?PU$RweTpX^2MQiVR%sB9JnVF)ks0-ucP`kJ}-QDrs)P!7};-
Hah(4GS=VMr

literal 0
HcmV?d00001

diff --git a/client.py b/client.py
index 494c508..4f1cae8 100644
--- a/client.py
+++ b/client.py
@@ -12,7 +12,6 @@ CLIENT_MULTICAST_PORT = 5973
 MY_HOST = socket.gethostname()
 MY_IP = socket.gethostbyname(MY_HOST)
 
-
 class Client():
     def __init__(self):
         self.currentLeader = ''
diff --git a/server.py b/server.py
index 0041a12..7a2eb5e 100644
--- a/server.py
+++ b/server.py
@@ -34,16 +34,13 @@ class Server():
         self.uuid = str(uuid.uuid4())
         self.participant = False
         
-
     def printwt(self, msg):
         current_date_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
         print(f'[{current_date_time}] {msg}')
-
     
     def print_group_view(self):
         print("Group view is:", self.serverList)
 
-
         #This function enables the server to listen to the server multicast port and reply the ip address
     def MulticastListenAndReply(self):
 
@@ -239,14 +236,14 @@ class Server():
                 print(election_message)
 
                 if election_message.get('isLeader') and self.participant:
-                    print('1: leader info weitergeben')
+                    print('leader info weitergeben')
                     self.leader_uuid = election_message['mid']
                     # forward received election message to left neighbour
                     self.participant = False
                     ring_socket.sendto(json.dumps(election_message).encode('utf-8'), neighbour_address)
                     print(f'Leader is {self.leader_uuid}')
                 elif election_message.get('mid') < self.uuid and not self.participant:
-                    print('2: mich vorschlagen')
+                    print('mich vorschlagen')
                     new_election_message = {
                         "mid": self.uuid,
                         "isLeader": False
@@ -256,11 +253,11 @@ class Server():
                     ring_socket.sendto(json.dumps(new_election_message).encode('utf-8'), neighbour_address)
                 elif election_message.get('mid') > self.uuid:
                     # send received election message to left neighbour
-                    print('3: Jemand anderes vorschlagen')
+                    print('Jemand anderes vorschlagen')
                     self.participant = True
                     ring_socket.sendto(json.dumps(election_message).encode('utf-8'), neighbour_address)
                 elif election_message.get('mid') == self.uuid and self.participant:
-                    print('4: Ich wurde als Leader definiert')
+                    print('Ich wurde als Leader definiert')
                     self.leader_uid = self.uuid
                     self.isLeader = True
                     new_election_message = {
@@ -272,12 +269,41 @@ class Server():
                     ring_socket.sendto(json.dumps(new_election_message).encode('utf-8'), neighbour_address)
                     print(f'I am Leader {self.leader_uuid}')
                 elif election_message.get('isLeader') and not self.participant:
-                    print('5: Leader ist gewählt, Nachricht wurde schon weiteregeben, ELECTION beenden')
+                    print('Leader ist gewählt, Nachricht wurde weiteregeben, ELECTION beenden')
         except Exception as e:
             print(f"An error occurred: {e}")
         finally:
             ring_socket.close()
 
+    def init_heartbeat(self):
+        self.leader_heartbeat_last_received = time.time()
+        self.is_leader = False
+        self.heartbeat_interval = 5  # seconds
+        self.missed_heartbeats_limit = 5
+        self.missed_heartbeats = 0
+        threading.Thread(target=self.heartbeat_monitor).start()
+        if self.is_leader:
+            threading.Thread(target=self.emit_heartbeat).start()
+
+    def emit_heartbeat(self):
+        while self.is_leader:
+            # Code to sends a heartbeat message
+            print("Heartbeat emitted by leader")
+            time.sleep(self.heartbeat_interval)
+
+    def heartbeat_monitor(self):
+        while True:
+            time_since_last_heartbeat = time.time() - self.leader_heartbeat_last_received
+            if time_since_last_heartbeat > self.heartbeat_interval:
+                self.missed_heartbeats += 1
+                print(f"Missed heartbeat detected. Count: {self.missed_heartbeats}")
+                if self.missed_heartbeats >= self.missed_heartbeats_limit:
+                    print("Missed heartbeats limit reached. Initiating leader election.")
+                    # Reset missed heartbeats count
+                    self.missed_heartbeats = 0
+                    # Code to initiate a new voting process to elect a new leader
+                    # This could involve calling a function from voting.py or similar logic
+            time.sleep(self.heartbeat_interval)
 
 # starting all simultaneously working procedures
 if __name__== '__main__':
-- 
GitLab