def handleElectionMessage(self, message, address): processId = message.params[0] if (int(processId) < self.sharedData['id']): log('sending OK for election ID ', message.params[1]) message = Message(MessageType.OK, str(self.sharedData['id']), message.params[1]) self.socket.sendMessage( message.toByteStr(), address, ) self.startElection()
def joinSwarm(self, address): print('(%s, %s) getting members' % (address[0], address[1]), flush=True) message = Message(MessageType.GET_MEMBERS, json.dumps(self.members)) print('New member (%s, %s) joining swarm' % (address[0], address[1]), flush=True) self.members.append(address) self.socket.sendto(message.toByteStr(), address)
def process_message(self, from_node, incoming_message): logging.info("Node %i is processing '%s' from node %i", self.node_number, incoming_message, from_node.node_number if from_node else -1) msg_type: MessageType = incoming_message.msg_type if MessageType.WAKEUP == msg_type: self.trigger_election() elif MessageType.ELECTION == msg_type: # Start the leader election process on this node. if not self.has_started: self.trigger_election() # Send answer back, unless this node has determined itself to be the leader (has highest ID). if not self.leader: answer_message: Message = Message(MessageType.ALIVE) from_node.receive(self, answer_message) elif MessageType.ALIVE == msg_type: if from_node.node_number > self.node_number: # Clear out the timer as we have gotten a response from a Node with a higher number/ID. self.election_message_sent_time_millis = None elif MessageType.VICTORY == msg_type: # Set winner as leader and stop the leader election process. self.leader = from_node Node.leader_elected = from_node self.is_running = False
def listen(self): while True: log('listening to receive message') response, address = self.socket.receive() if (response is None and address is None): continue message = Message.parse(response) if (message.type == MessageType.JOIN_SWARM): self.saveNewMemberToSwarm(address) if (self.sharedData['leader']['isSelf']): self.announceLeadership(address) continue if (message.type == MessageType.LEADER): self.sharedData['leader']['isSelf'] = False self.sharedData['leader']['address'] = address log('Leader is ', address) continue if (message.type == MessageType.ALIVE): self.socket.send(MessageType.ALIVE_OK, address) continue if (message.type == MessageType.ALIVE_OK): self.sharedData['leader']['isAlive'] = True continue if (message.type == MessageType.ELECTION): self.handleElectionMessage(message, address) continue if (message.type == MessageType.OK): log('Received OK for election id ', message.params[1]) self.sharedData['elections'][ message.params[1]]['isLeader'] = False continue raise NotImplementedError(message.type)
def receive(self): response, address = self.socket.recvfrom(BUFFERSIZE) message = Message.parse(response) if (self.sharedData['failProcess']): if (message.type != MessageType.LEADER): log('%s message received ignored' % message.type.name) return (None, None) self.storeStatistics(message.type, 'received') log('%s message received' % message.type.name) return (response, address)
def sendMessage(self, message, address): messageParsed = Message.parse(message) name = messageParsed.type.name if (self.sharedData['failProcess']): log("%s message sent blocked" % name) return log("%s message sent" % name) self.storeStatistics(messageParsed.type, 'sent') return self.socket.sendto(message, address)
def on_node_elected_as_leader(self): logging.info("Node %i has selected itself as leader", self.node_number) Node.leader_elected = self self.leader = self victory_message: Message = Message(MessageType.VICTORY) for node in self.all_nodes: if self == node: continue node.receive(self, victory_message) self.is_running = False
def startElection(self): log("Starting election...") electionId = str(threading.get_ident()) log('ELECTION STARTED WITH ID ', electionId) self.sharedData['elections'][electionId] = {"isLeader": True} for member in self.sharedData['swarmMembers']: message = Message(MessageType.ELECTION, str(self.sharedData['id']), electionId) self.socket.sendMessage( message.toByteStr(), tuple(member), ) time.sleep(SECONDS_TO_WAIT_FOR_OK_RESPONSES) if (self.sharedData['elections'][electionId]['isLeader']): log("I'm the new leader!") self.sharedData['leader']['isSelf'] = True self.broadcastLeadership() else: log("I'm NOT the new leader!")
def initListening(self): print('tracker will start listening...', flush=True) while True: response, address = self.socket.recvfrom(1024) message = Message.parse(response) if (message.type == MessageType.GET_MEMBERS): self.joinSwarm(address) continue if (message.type == MessageType.KILL): print('finishing', flush=True) os._exit(0) raise NotImplementedError(message.type)
def run_simulation(simulation_node_count): # Initialize the nodes. nodes = [] for i in range(0, number_of_nodes_in_simulation): nodes.append(Node(i + 1)) # After initialization, set node neighbours (next neighbour in the array). for i in range(len(nodes)): nodes[i].set_all_nodes(nodes) Node.expected_leader = nodes[-1] # Randomly have nodes detect leader failure number_of_nodes_to_wake = random.randint(1, number_of_nodes_in_simulation) logging.info("Waking up %i node(s)", number_of_nodes_to_wake) nodes_shuffled = nodes.copy() random.shuffle(nodes_shuffled) nodes_to_wake = [] for i in range(0, number_of_nodes_to_wake): nodes_to_wake.append(nodes_shuffled[i]) # Define the function that will run on the new threads def run_on_thread(node): logging.info("Thread starting for node %i", node.node_number) node.run() logging.info("Thread stopped for node %i", node.node_number) # Create all threads (with function listed above) threads = [] for node in nodes: threads.append(threading.Thread(target=run_on_thread, args=(node, ))) # Start threads for thread in threads: thread.start() # Wake up nodes for node_to_wake in nodes_to_wake: wakeup_message = Message(MessageType.WAKEUP) node_to_wake.receive(None, wakeup_message) # Join threads after they're done for thread in threads: thread.join() return nodes
def trigger_election(self): logging.info("Node %i has started new leader election", self.node_number) self.has_started = True # If the current node has the highest node number, it's the leader. Inform the other nodes of this. if self.all_nodes[-1] == self: self.on_node_elected_as_leader() else: # Send an election message to all nodes with a higher node number than current node's number. election_message = Message(MessageType.ELECTION) # node_number is array index+1 (so don't do node_number-1 as that will lead to nodes messaging themselves). for i in range(self.node_number, len(self.all_nodes)): self.all_nodes[i].receive(self, election_message) self.election_message_sent_time_millis = current_time_millis()
def __init__(self, conversation_source: Dict[str, Any]) -> None: self.logger = logging.getLogger( 'MessengerViz.coversation.Conversation') self.participants = [] for p in conversation_source["participants"]: self.participants.append(p.get("name", "ParseError")) self.logger.debug('Detected %d participants.', len(self.participants)) self.messages = [] for msg in conversation_source["messages"]: self.messages.append(Message(msg)) self.logger.debug('Detected %d messages.', len(self.messages)) self.reactions = {} for msg in self.messages: try: self.reactions.update(msg.reactions) except AttributeError: # No reaction in that message pass self.title = conversation_source["title"] self.is_still_participant = conversation_source["is_still_participant"] self.thread_type = conversation_source["thread_type"] self.thread_path = conversation_source["thread_path"] self.message_count_by_sender = {}
def finishProcess(address, mySocket): print(address, flush=True) message = Message(MessageType.KILL) mySocket.sendto(message.toByteStr(), address)
def add_message(self, sender, message_type, size, message): new_message = Message(self.next_message_id, self.id, sender, message_type, size, message) self.next_message_id += 1 self.messages.append(new_message) return new_message.id
def send(self, messageType, address): return self.sendMessage(Message(messageType).toByteStr(), address)
def getSwarmMembers(self): self.socket.send(MessageType.GET_MEMBERS, self.trackerAddress) response, address = self.socket.receive() message = Message.parse(response) self.sharedData['swarmMembers'] = json.loads(message.params[0])
def setUpClass(cls): cls.maxDiff = None cls.skeleton_JSON = FileIO() cls.skeleton_JSON.open_json("test/Messages/message_skeleton_text.json") cls.message = Message(cls.skeleton_JSON.data)