from datetime import datetime, timedelta import pause from source.behaviors import roles from source.behaviors.roles import base class UndefinedRole(base.BaseRole): """ Role used when the machine is looking for how it should insert itself in the network """ def handle(self) -> None: # calculate a timeout of when stopping to look for new peers timeout = self.manager.peer.peers.last_added + timedelta(seconds=5) # if the timeout have not been reach, wait for it and restart if not datetime.now() > timeout: pause.until(timeout) return # SCENARIO 1 - empty network # filter ourselves out of the remote peers remote_peers = { address: peer for (address, peer) in self.manager.peer.peers.items() if not self.manager.communication.is_address_local(address) } # if no other peers have been found if len(remote_peers) == 0: # declare ourselves as the master of the network self.manager.role.current = roles.MasterRole(self.manager) return # SCENARIO 2 - network with a master # list all the peers considered as masters master_peers = { address: peer for (address, peer) in remote_peers.items() if peer.master } # if there is a master, become a slave if len(master_peers) >= 1: # get the first master information master_address, master_peer = master_peers[0] # declare ourselves as a slave of the network self.manager.role.current = roles.SlaveRole(self.manager, master_address) return # SCENARIO 3 - network with no master # TODO(Faraphel): elect the machine with the lowest ping in the network raise NotImplementedError("Not implemented: elect the machine with the lowest ping as a master.")