Ejemplo n.º 1
0
    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())
Ejemplo n.º 2
0
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