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""" self.params=params # event queue, used for inter-thread communication self.events = NotificationQueue() self.connectors = [] EventFactory.init(self) EventFactory.register(PeerEventFactory.TYPE, PeerEventFactory()) EventFactory.register(ControlEventFactory.TYPE, ControlEventFactory()) # network communication with peers is handled by this object self.peerConnector = UDPConnector(PeerEventParser(), self.events, params) self.connectors.append(self.peerConnector) if (not params.bot): self.controlConnector = XMLRPCConnector(ControlEventParser(), self.events, params) self.connectors.append(self.controlConnector) else: self.controlConnector = None id_ = self.createId() position = Position(params.pos_x, params.pos_y) address = Address(params.host, params.port) # call parent class constructor Entity.__init__(self, id_, position, params.orientation, params.awareness_radius, params.calibre, params.pseudo, address) # maximum expected number of neighbours. self.exp = params.expected_neighbours # our IP address or 'localhost' if not specified in config file self.host = params.host self.alive = True self.logger = logging.getLogger('root') self.logger.debug('node started') # manage all peers #peersParams = params.getPeersParams() self.peersManager = PeersManager(self, params) # set world size in Geometry class Geometry.SIZE = params.world_size # periodic tasks self.periodic = [] self.state = None self.setState(state.NotConnected())
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""" self.params=params # event queue, used for inter-thread communication self.events = NotificationQueue() self.connectors = [] EventFactory.init(self) EventFactory.register(PeerEventFactory.TYPE, PeerEventFactory()) EventFactory.register(ControlEventFactory.TYPE, ControlEventFactory()) # network communication with peers is handled by this object self.peerConnector = UDPConnector(PeerEventParser(), self.events, params) self.connectors.append(self.peerConnector) if (not params.bot): self.controlConnector = XMLRPCConnector(ControlEventParser(), self.events, params) self.connectors.append(self.controlConnector) else: self.controlConnector = None id_ = self.createId() position = Position(params.pos_x, params.pos_y) address = Address(params.host, params.port) # call parent class constructor Entity.__init__(self, id_, position, params.orientation, params.awareness_radius, params.calibre, params.pseudo, address) # maximum expected number of neighbours. self.exp = params.expected_neighbours # our IP address or 'localhost' if not specified in config file self.host = params.host self.alive = True self.logger = logging.getLogger('root') self.logger.debug('node started') # manage all peers #peersParams = params.getPeersParams() self.peersManager = PeersManager(self, params) # set world size in Geometry class Geometry.SIZE = params.world_size # periodic tasks self.periodic = [] self.state = None self.setState(state.NotConnected()) def createId(self): return self.params.host + ':' + str(self.params.port) def getPeersManager(self): return self.peersManager def setExpectedPeers(self, nbPeers): """ Set the expected numbetr of peers for the node""" self.exp = nbPeers self.peersManager.setExpectedPeers(nbPeers) def setState(self, stateObject): """ Change the current state of the node.""" self.state = stateObject self.logger.debug("State " + type(stateObject).__name__) stateObject.setNode(self) stateObject.setLogger(self.logger) stateObject.activate() def setPosition(self, position): super(Node, self).setPosition(position) self.peersManager.recalculate() def dispatch(self, event): """ Send an event. event : the event to send. """ connector = None event_type = event.getType() if event_type == PeerEvent.TYPE: connector = self.peerConnector elif event_type == ControlEvent.TYPE: connector = self.controlConnector else: raise InternalError('Unknown event type ' + event_type) if connector is not None: connector.send(event) def exit(self): """ stop the node and exit """ # 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 for c in self.connectors: if c.isAlive(): c.stop() c.join() self.alive = False def startPeriodicTasks(self): """ Start all the periodic tasks of this node, like sending heartbeats""" hb = periodic.Heartbeat(self) self.periodic.append(hb) hb.start() if self.params.memdebug: import gc gc.set_debug(gc.DEBUG_STATS | gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_INSTANCES | gc.DEBUG_OBJECTS) md = periodic.Memdump() self.periodic.append(md) md.start() def mainLoop(self): """ Main loop of the program """ # start control connector for c in self.connectors: c.start() try: while self.alive: # Check our connectors are still there for c in self.connectors: if not c.isAlive(): print "connector aborted" self.exit() raise ConnectorError() 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: fun = self.state.__getattribute__(request) except: self.logger.debug("unknown request "+ request) else: try: fun(event) except: exception_type, value, tb = sys.exc_info() self.logger.debug(exception_type) self.logger.debug(value) stack_trace = traceback.format_tb(tb) self.logger.debug(stack_trace) del tb del value sys.exc_clear() except Exception, e: print e self.logger.debug("end of main loop") try: self.exit() except: pass