-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode.py
More file actions
97 lines (82 loc) · 3.14 KB
/
node.py
File metadata and controls
97 lines (82 loc) · 3.14 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from message import Message
from minimal_spanning_tree_builder import extract_minimal_spanning_tree
class Node:
"""
A network Node
"""
def advertise(self, node):
"""
Adds a new node to neighbor
Parameters
----------
node: Node
The new neighbor
"""
if node not in self.neighbors:
self.neighbors.append(node)
def has_neighbor(self, node):
return node in self.neighbors
def __repr__(self):
return str(self.id)
def __init__(self, id, network_interface):
self.neighbors = []
self.id = id
self.network_interface = network_interface
self.minimal_spanning_tree = None
self.messages = []
def __hash__(self):
# ID is unique for nodes created by network.create_node
# ==> __hash__ is collision free and faster than calling super().hash()
return self.id
def send_message(self, message):
"""
Sends a message if the next hop in the messages path is a neighbor
Parameters
----------
message: Message
The message to send
"""
path_tree = message.header["path_tree"]
next_hop = path_tree.data
if self.has_neighbor(next_hop):
self.network_interface.send(self, next_hop, message)
else:
print(
f"Warning: {str(self)} tried sending a message to a node not its neighbor: {next_hop}"
)
def receive(self, message):
"""
Callback for when a message is received by this node
Parameters
----------
message: Message
The message received
"""
self.messages.append(message.body)
path_tree = message.header["path_tree"]
for child_tree in path_tree.children:
new_message = message.clone()
new_message.header["path_tree"] = child_tree
self.send_message(new_message)
message = None
def invoke_broadcast(self, content):
"""
Invokes a broadcast to all nodes reachable
If this is the first broadcast send by this node,
then a minimal spanning tree, containing all nodes reachable,
will be constructed first. The complexity for this initial call
is therefore in O(n*log(n)). All calls after that are in O(n)
Parameters
----------
content: Any
The content of the message to send
"""
if self.minimal_spanning_tree is None:
print("Creating MST...")
self.minimal_spanning_tree = extract_minimal_spanning_tree(self)
print("MST created")
message = Message(self.minimal_spanning_tree, content)
self.receive(message) # Call receive to drop "message zero" into the root nodes in port
network = self.network_interface.network
# Simulate network activity
network.start()