def __init__(self, params): """ All informations about this node: host --> ip if the node, network_port, GUI_port, posX, posY, ar, ca, ori --> a point, exp --> expected number of neighbour, pseudo""" # event queue, used for inter-thread communication self.events = NotificationQueue() # network communication with peers is handled by this object netParams = params.getNetParams() self.peerConnector = UDPConnector("peer", self.events, netParams) controlParams = params.getControlParams() self.controlConnector = XMLRPCConnector("control", self.events, controlParams) # set the solipsis protocol used engineParams = params.getEngineParams() self.engine = V0_2_5_Engine(self, engineParams) self.controlEngine = ControlEngine(self, engineParams) self.internalEngine = InternalEngine(self, engineParams) position = [params.posX, params.posY] # call parent class constructor Entity.__init__(self, position, params.ori, params.ar, params.caliber, params.pseudo) self.id = "unknown" # maximum expected number of neighbours. self.exp = params.exp # our IP address or 'localhost' if not specified in config file self.host = params.host self.alive = True self.logger = params.rootLogger # manage all peers peersParams = params.getPeersParams() self.peersManager = PeersManager(self, peersParams) # set world size in Geometry class Geometry.SIZE = params.world_size self.params=params
class Node(Entity): def __init__(self, params): """ All informations about this node: host --> ip if the node, network_port, GUI_port, posX, posY, ar, ca, ori --> a point, exp --> expected number of neighbour, pseudo""" # event queue, used for inter-thread communication self.events = NotificationQueue() # network communication with peers is handled by this object netParams = params.getNetParams() self.peerConnector = UDPConnector("peer", self.events, netParams) controlParams = params.getControlParams() self.controlConnector = XMLRPCConnector("control", self.events, controlParams) # set the solipsis protocol used engineParams = params.getEngineParams() self.engine = V0_2_5_Engine(self, engineParams) self.controlEngine = ControlEngine(self, engineParams) self.internalEngine = InternalEngine(self, engineParams) position = [params.posX, params.posY] # call parent class constructor Entity.__init__(self, position, params.ori, params.ar, params.caliber, params.pseudo) self.id = "unknown" # maximum expected number of neighbours. self.exp = params.exp # our IP address or 'localhost' if not specified in config file self.host = params.host self.alive = True self.logger = params.rootLogger # manage all peers peersParams = params.getPeersParams() self.peersManager = PeersManager(self, peersParams) # set world size in Geometry class Geometry.SIZE = params.world_size self.params=params def getPeersManager(self): return self.peersManager def updatePosition(self, newPosition): """ update the position of the node newPosition : the new poition of the node , a list [posX, posY] """ self.node.position = newPosition manager = self.getPeersManager() # re compute all positions of neighbours manager.update() def send(self, peer, message): """ Send a message to a peer message : a solispsis message, e.g. 'HEARTBEAT;10.193.161.35:33363' peer : a Peer object resenting the recipient of the message """ #netEvent = NetworkEvent(message) #netEvent.setRecipient(peer.getNetAddress()) #self.net.send(netEvent) self.peerConnector.send(peer, message) def sendController(self, message): self.controlConnector.send(message) def enterSolipsis(self): """ Enter Solipsis world, we consider that we have entered solipsis as soon as have we are connected to one Solipsis entity Raise: SolipsisConnectionError when a timeout expires Return : True if the connection succeded """ time_stamp = time.time() #message = "KNOCK;SOLIPSIS 0.3" message = "HI" timeout = self.params.connection_timeout while True: # retrieve peer manager = self.getPeersManager() peer = manager.getRandomPeer() # send message self.send(peer, message) time.sleep(0.5) # we got an answer, for one of our Hi messages: we have entered Solipsis if not self.events.empty(): self.alive = True return True # Time out : impossible to connect if time.time() > time_stamp + timeout: self.logger.critical("Time out: cannot connect to Solipsis") raise SolipsisConnectionError() def exit(self): """ stop the node and exit """ # stop the network thread self.peerConnector.stop() # we do not need to stop the controlConnector. The controlConnector # stopped after sending us the exit message # --> self.controlConnector.stop() not needed ! # wait for the other threads before exiting self.peerConnector.join() self.controlConnector.join() self.alive = False def mainLoop(self): """ Main loop of the program """ # start control connector self.controlConnector.start() # start peer connector self.peerConnector.start() try: # enter solipsis : send the first message #self.enterSolipsis() pass except: self.logger.critical("cannot enter Solipsis, exiting...") self.exit() raise while self.alive: self.events.acquire() # no events to process - wait for a notification from other threads if self.events.empty(): self.events.wait() # We can immediately release the lock: we know that there is an item available # because this is the only thread that consumes items from the queue. # If other threads can consume item then we must first get the item then # release the lock self.events.release() # process one event in queue event = self.events.get() type = event.type() #self.logger.debug("%s - %s - %s ", event.name(), event.type(), # event.data()) if( type == Event.PEER ): self.engine.process(event) elif( type == Event.CONTROL): self.controlEngine.process(event) elif type == Event.INTERNAL: self.internalEngine.process(event) else: self.logger.critical("Unknown event type" + type) self.logger.debug("end of main loop") def processPeriodicEvent(self, event): """ Process periodic tasks Send heartbeat message Or check global connectivity """ # TO DO self.logger.critical("processPeriodicEvent not implemented")
class Node(Entity): def __init__(self, params): """ All informations about this node: host --> ip if the node, network_port, GUI_port, posX, posY, ar, ca, ori --> a point, exp --> expected number of neighbour, pseudo""" # event queue, used for inter-thread communication self.events = NotificationQueue() # network communication with peers is handled by this object netParams = params.getNetParams() self.peerConnector = UDPConnector("peer", self.events, netParams) controlParams = params.getControlParams() self.controlConnector = XMLRPCConnector("control", self.events, controlParams) intParams = params.getInternalParams() self.internalConnector = InternalConnector('internal', self.events, intParams) position = Position(params.posX, params.posY) # call parent class constructor Entity.__init__(self, position, params.ori, params.ar, params.caliber, params.pseudo) self.id = "unknown" # maximum expected number of neighbours. self.exp = params.exp # our IP address or 'localhost' if not specified in config file self.host = params.host self.alive = True self.logger = params.rootLogger # manage all peers peersParams = params.getPeersParams() self.peersManager = PeersManager(self, peersParams) # set world size in Geometry class Geometry.SIZE = params.world_size self.params=params self.state = None self.setState('NotConnected') def getPeersManager(self): return self.peersManager def setState(self, stateClass): stmt = 'state.' + stateClass + '(self, self.logger)' try: self.state = eval(stmt) except: raise SolipsisInternalError('unknown state ' + stateClass) def fire(self, event): """ Send an event. event : the event to send. """ connector = None type = event.getType() if type == 'peer': connector = self.peerConnector elif type == 'control': connector = self.controlConnector elif type == 'internal': connector = self.internalConnector else: raise SolipsisInternalError('Unknown event type ' + type ) connector.send(event) def exit(self): """ stop the node and exit """ # stop the network thread self.peerConnector.stop() self.internalConnector.stop() # we do not need to stop the controlConnector. The controlConnector # stopped after sending us the exit message # --> self.controlConnector.stop() not needed ! # wait for the other threads before exiting self.peerConnector.join() self.controlConnector.join() self.internalConnector.join() self.alive = False def mainLoop(self): """ Main loop of the program """ # start control connector self.controlConnector.start() # start peer connector self.peerConnector.start() # start internal connected : needed for periodic tasks self.internalConnector.start() while self.alive: self.events.acquire() # no events to process - wait for a notification from other threads if self.events.empty(): self.events.wait() # We can immediately release the lock: we know that there is an item available # because this is the only thread that consumes items from the queue. # If other threads can consume item then we must first get the item then # release the lock self.events.release() # process one event in queue event = self.events.get() request = event.getRequest() try: # process this request according to our current state # e.g.: stmt='self.state.NEAREST(event)' stmt = 'self.state.' + request + '(event)' eval(stmt) except: self.logger.debug(sys.exc_info()[0]) self.logger.debug(sys.exc_info()[1]) self.logger.debug("unknown request "+ stmt) self.logger.debug("end of main loop")