import time from datetime import datetime, timedelta from . import base, MasterRole from source import packets from .SlaveRole import SlaveRole from ...managers import Manager from ...utils.crypto.type import CipherType class UndefinedRole(base.BaseRole): """ Role used when the peer have no defined state, for example just after starting. It looks for the current network peers state and try to integrate itself inside. """ def __init__(self, manager: "Manager"): super().__init__(manager) self.old_peers: list[packets.PeerPacket] = [] self.previous_discovery: datetime = datetime.now() def handle(self): # discover new peers packet = packets.DiscoveryPacket() self.manager.communication.broadcast(packet, CipherType.PLAIN) # wait for new messages time.sleep(1) # check if a new peer have been registered if self.manager.peers != self.old_peers: self.old_peers = self.manager.peers.copy() self.previous_discovery = datetime.now() # check if no more peers have been found in the previous seconds if datetime.now() - self.previous_discovery >= timedelta(seconds=5): # SCENARIO 1 - empty network # filter ourselves out of the remote peers remote_peers = { address: peer for (address, peer) in self.manager.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 = 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: master_address, master_peer = master_peers[0] # declare ourselves as a slave of the network self.manager.role.current = SlaveRole(self.manager, master_address) # 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.")