Esempio n. 1
0
    def AROUND(self, event):
        """ A peer sent us an AROUND message """
        # cancel timer since we got our response
        self.timer.cancel()

        peer = event.createRemotePeer()
        # current number of neighbours
        nbNeighbours = len(self.neighbours)
        # last neighbour found
        last = self.neighbours[nbNeighbours-1]

        nodePos = self.node.getPosition() # our position
        bestPos = self.best.getPosition() # position of best node

        peerPos = Geometry.relativePosition(peer.getPosition(),
                                                 self.node.getPosition())

        # check if turn ends : we have at least 3 neighbours and either we got back
        # to the first peer (=> turn completed) or our last neighbour was in the
        # left half plane and this peer is in the right half plane
        if ( nbNeighbours > 2 ) and (peer.getId() == self.best.getId()) or (
            not Geometry.inHalfPlane(bestPos, nodePos, last.getPosition())
            and Geometry.inHalfPlane(bestPos, nodePos, peerPos) ):

            # Our awarenesse radius is the distance between us and our closest
            # neighbour, because we are sure to know all the entities between us
            # and the best.
            bestRelativePos = Geometry.relativePosition(bestPos, nodePos)
            minDistance = Geometry.distance(bestRelativePos, nodePos)
            self.node.setAwarenessRadius(minDistance)

            # register these peers with the peerManager and connect !
            manager = self.node.getPeersManager()
            for p in self.neighbours:
                # FIXME : should we add the peer upon receiving the CONNECT msg?
                manager.addPeer(p)
                factory = EventFactory.getInstance(PeerEvent.TYPE)
                hello = factory.createHELLO()
                hello.setRecipientAddress(p.getAddress())
                self.node.dispatch(hello)

            self.node.setState(Connecting())
        else:
            # add this peer to our list of neighbours
            self.addPeerAround(peer)

            # send this peer a queryaround message
            bestDist = Geometry.distance(bestPos, nodePos)
            factory = EventFactory.getInstance(PeerEvent.TYPE)
            queryaround = factory.createQUERYAROUND(self.best.getId(), bestDist)
            queryaround.setRecipientAddress(peer.getAddress())
            self.node.dispatch(queryaround)
            self.startTimer()
Esempio n. 2
0
    def getBadGlobalConnectivityPeers(self):
        """ Check if global connectivity is ensured

        Return a pair of entities not respecting property or an empty set.
        First entity should be used to search clockwise and the second one ccw"""
        result = []

        nodePos = self.node.getPosition()
        length = self.getNumberOfPeers()

        if length == 0:
            return []

        if length == 1:
            (peer,) = self.peers.values()
            return [peer, peer]

        for index in range(length):
            ent = self.ccwPeers.ll[index]
            nextEnt = self.ccwPeers.ll[ (index+1) % length ]
            entPos = ent.getPosition()
            nextEntPos = nextEnt.getPosition()
            if not Geometry.inHalfPlane(entPos, nodePos, nextEntPos):
                return [ent, nextEnt]
        return []
Esempio n. 3
0
    def getPeerAround(self, targetPosition, emitter_id, isClockWise=True):
        """ Return the peer that is the closest to a target position and that
        is in the right half plane.
        targetPosition : target position which we are looking around
        isClockWise : boolean indicating if we we searching in the right or the
        left half-plane - optional
        Return : a peer or None if there is no peer in the half plane
        """
        found = False
        around = None
        distClosest = 0
        nodePosition = self.node.getPosition()
        for p in self.peers.values():
            if p.getId() == emitter_id:
                continue
            if Geometry.inHalfPlane(nodePosition, targetPosition,
                                    p.getPosition()) == isClockWise:
                # first entity in right half-plane
                if not found:
                    found = True
                    around = p
                    distClosest = Geometry.distance(targetPosition, p.getPosition())
                else:
                    dist = Geometry.distance(targetPosition, p.getPosition())
                    # this peer is closer
                    if dist < distClosest:
                        around = p
                        distClosest = dist

        return around
Esempio n. 4
0
    def necessaryPeers(self):
        """ Returns the list of peers that are necessary for our global connectivity. """

        n = len(self.ccwPeers)
        if n < 4:
            return self.enumeratePeers()
        result = []
        for i in xrange(n):
            pred_pos = self.ccwPeers.ll[i - 2].getPosition()
            pos = self.node.getPosition()
            succ_pos = self.ccwPeers.ll[i].getPosition()
            if not Geometry.inHalfPlane(pred_pos, pos, succ_pos):
                result.append(self.ccwPeers.ll[i - 1])

        return result
Esempio n. 5
0
    def getWorstPeers(self):
        """ Return a list of peers with which we should disconnect. Removing these
        peers must NOT break the global connectivity rule.
        Return a list of peers or [] if we cannot remove a peer
        """
        if not self.hasTooManyPeers():
            return []

        # filter list of neighbors
        # keep only entities not in Awareness Area which do not provoke mis-respect
        # of Global Connectivity Rule

        FilterList = []
        endFilter = True
        indexFilter = len(self.distPeers) - 1
        nodePos = self.node.getPosition()

        while endFilter and indexFilter > 0:
            ent = self.distPeers.ll[indexFilter]
            distEnt = Geometry.distance(ent.getPosition(), nodePos)

            # first, verify that ent is not in Awareness Area
            if distEnt > self.node.getAwarenessRadius() :
                # and that we are not in its AR
                if distEnt > ent.getAwarenessRadius():

                    indInCcw = self.ccwPeers.ll.index(ent)
                    successor = self.ccwPeers.ll[(indInCcw + 1) % len(self.ccwPeers)]
                    predecessor = self.ccwPeers.ll[indInCcw - 1]

                    # then verify that ent is not mandatory for Rule respect
                    if Geometry.inHalfPlane(predecessor.getPosition(), nodePos,
                                            successor.getPosition()):
                        FilterList.append(ent)

            else:
                # stop iteration because all following entities are in Awareness
                # Radius
                endFilter = False

            indexFilter -= 1

        return FilterList