-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnode.py
70 lines (58 loc) · 2.33 KB
/
node.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
"""
node.py
Description:
This file contains the definition of the node class.
It provides the basic functionality for each node in the system.
This functionality includes receiving messages, handeling messages and
sending messages.
"""
import threading
import logging
import json
import random
import signal
import socket
import time
class Node:
def __init__(self, host, node_hosts, leader_port):
self.host = host
self.port = host[1]
self.node_hosts = node_hosts
self.leader = leader_port
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(("", self.port))
self.is_connected = True
logging.info("{} listining on port {}".format(self, self.port))
# Waits for incomming messages and calls on_message function to handle it
def run(self):
while self.is_connected:
data, addr = self.socket.recvfrom(1024)
message = json.loads(data.decode())
logging.debug("{}, received message: {} from {}".format(self, message, addr))
self.on_message(addr, message)
# The same as run, only with a artificial delay for testing
def run_delayed(self):
while self.is_connected:
time.sleep(.05) # Artificial delay
data, addr = self.socket.recvfrom(1024)
message = json.loads(data.decode())
logging.debug("{}, received message: {} from {}".format(self, message, addr))
self.on_message(addr, message)
# Sends 'data' to all other known hosts by looping over them
def send_to_all(self, data):
for host in self.node_hosts:
self.send(host, data)
# Sends a message to a specific host
def send(self, addr, message):
logging.debug("{}, sent message: {} to {}".format(self, message, addr))
self.socket.sendto(json.dumps(message).encode(), addr)
# This function handles incomming messages and will be overloaded by child classes
def on_message(self, addr, message):
pass
# Allows you to print a node as a string
def __str__(self) -> str:
return "Node:{}:{}".format(self.host[0], self.host[1])
# Allows you to print a node as a string
def __repr__(self) -> str:
return self.__str__()