Skip to content
Snippets Groups Projects
Commit adf52f7c authored by Katharina's avatar Katharina
Browse files

comments

parent e7caf57c
No related merge requests found
......@@ -7,10 +7,10 @@ import threading
broadcast_ip = '255.255.255.255'
broadcast_port = 55555
# Erstelle eine eindeutige Server-ID
# creates unique server-ID
server_id = str(uuid.uuid4())
# Socket für Broadcast erstellen
# Socket for broadcast
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
......@@ -18,18 +18,18 @@ server_socket.bind(('', broadcast_port))
print(f"Server is running with ID {server_id} and broadcasting on port {broadcast_port}...")
# Globale Liste für bekannte Server-IDs
# global list for known server-IDs (which does not work atm)
active_servers = set()
current_leader = None
# Broadcast-Funktion
# broadcast-function
def broadcast(message):
"""Sendet Nachrichten an alle Server-IDs im Netzwerk"""
full_message = f"[{server_id}] {message}".encode()
server_socket.sendto(full_message, (broadcast_ip, broadcast_port))
# Listener-Funktion
# listener-function
def listen(queue):
"""Empfängt Nachrichten von anderen Prozessen und leitet sie weiter."""
while True:
......@@ -37,42 +37,41 @@ def listen(queue):
message, client_address = server_socket.recvfrom(4096)
decoded_message = message.decode()
# Ignoriere Nachrichten vom eigenen Server/ also running for clients from this ip
# ignore messages from own server-ID/ also running for clients from this ip
if decoded_message.startswith(f"[{server_id}]"):
continue
print(f"Received from {client_address}: {decoded_message}")
# Nachricht in die Queue legen, damit der Broadcast-Prozess darauf reagieren kann
# put message in queue, that broadcast process can react
queue.put(decoded_message)
except socket.error as e:
print(f"Socket error occurred: {e}")
break
# Leader Election Funktion
# leader election function
def start_election(queue):
"""Startet die Leader Election basierend auf empfangenen Nachrichten."""
global current_leader
print("Starting election...")
broadcast(f"START_ELECTION: {server_id}") #sends broadcast, ignores his own id only in listen function
#current_leader = None
timeout = time.time() + 15 # 5 Sekunden auf Antworten warten
timeout = time.time() + 20 # wait 20 secs for answers
highest_id = server_id
while time.time() < timeout:
# Auf Nachrichten aus der Queue warten
# wait for messages from queue
try:
message = queue.get(timeout=1)
# Nachricht verarbeiten
# processing messages
if "START_ELECTION" in message:
sender_uuid = message.split(": ")[1]
#print("extracted uuid?:", sender_uuid)
active_servers.add(sender_uuid)
print(f"Received UUID for election: {sender_uuid}")
# Vergleich der UUIDs für Leader Election
# compare UUIDs for leader election
if sender_uuid > highest_id:
highest_id=sender_uuid
print(f"Received higher ID {sender_uuid}, forwarding...")
......@@ -83,13 +82,13 @@ def start_election(queue):
print(f"Received lower ID {sender_uuid}, sending own ID...")
broadcast(f"START_ELECTION: {server_id}")
else:
# Wir sind der Leader
# you are the leader:
current_leader = server_id
broadcast(f"LEADER: {server_id}")
print(f"I am the leader: {server_id}")
elif "LEADER" in message:
# Leader wurde gewählt
# leader was elected
leader_uuid = message.split(": ")[1]
current_leader = leader_uuid
print(f"Leader elected: {current_leader}")
......@@ -99,7 +98,7 @@ def start_election(queue):
except multiprocessing.queues.Empty:
continue
# Nach Timeout: Eigener Server wird Leader, falls niemand anderes gewählt wurde
# after timeout: own server becomes leader, if no other has been chosen
if highest_id == server_id:
current_leader = server_id
broadcast(f"LEADER {server_id}")
......@@ -107,41 +106,42 @@ def start_election(queue):
else:
print(f"Leader election finished, leader is {highest_id}")
################### Heartbeat-Funktion
################### Heartbeat-function not working###########################
def send_heartbeat():
"""Sendet regelmäßig Heartbeat-Nachrichten, um die Server-ID aktiv zu halten."""
while True:
broadcast(f"HEARTBEAT: {server_id}")
time.sleep(3) # Alle 3 Sekunden
time.sleep(3) # sends every 3 seconds
def monitor_heartbeats():
"""Überprüft die aktiven Server anhand von Heartbeat-Nachrichten."""
global active_servers
while True:
time.sleep(6) # Alle 6 Sekunden überprüfen
time.sleep(6) # checks every 6 seconds
now = time.time()
active_servers = {server for server, last_seen in active_servers.items() if now - last_seen < 6}
print(f"Active servers: {active_servers}")
################################################################################
# Main
if __name__ == "__main__":
# Queue für die Kommunikation zwischen Prozessen
# queue for communication between processes
message_queue = multiprocessing.Queue()
# Prozesse erstellen
# create processes
listener_process = multiprocessing.Process(target=listen, args=(message_queue,))
#time.sleep(10)
election_process = multiprocessing.Process(target=start_election, args=(message_queue,))
# Heartbeat in einem separaten Thread
# heartbeat in seperate thread###########
heartbeat_thread = threading.Thread(target=send_heartbeat, daemon=True)
# Prozesse starten
# start processes
listener_process.start()
election_process.start()
try:
# Hauptprozess wartet auf Beendigung der Subprozesse
# main process is waiting for the sub processes to finish
listener_process.join()
election_process.join()
except KeyboardInterrupt:
......
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment