示例#1
0
    def updateLists(self, response, key, host, port, closestyet, x=0):
        logger.info("FN: received kfindnode %s response from %s:%d" 
                % (self.abbrv, host, port))
        self.debugpath.append("FN: rec. resp from %s:%d" % (host, port))
        if not isinstance(response, dict):
            # a data value is being returned from findval
            # XXX: moved this bit into findval and call parent for the rest
            if response == None:
                logger.warn("got None from key=%s, %s:%d, x=%d, this usually"
                        " means that the host replied None to a findval query" 
                        % (key, host, port, x))
            # if we found the fencoded value data, return it
            return defer.succeed(response)
        logger.debug("updateLists(%s)" % response)
        if len(response['k']) == 1 and response['k'][0][2] == key:
            # if we've found the key, don't keep making queries.
            logger.debug("FN: %s:%d found key %s" % (host, port, key))
            self.debugpath.append("FN: %s:%d found key %s" % (host, port, key))
            if response['k'][0] not in self.kclosest:
                self.kclosest.insert(0,response['k'][0])
                self.kclosest = self.kclosest[:FludkRouting.k]
            return defer.succeed(response)

        #for i in response['k']:
        #   print "   res: %s:%d" % (i[0], i[1])
        id = long(response['id'], 16)
        responder = (host, port, id)
        if responder in self.outstanding:
            self.outstanding.remove(responder)
        self.queried[id] = (host, port)

        knodes = response['k']
        for n in knodes:
            if not self.queried.has_key(n[2])\
                    and not n in self.pending and not n in self.outstanding:
                self.pending.append((n[0], n[1], n[2]))
            if n not in self.kclosest:
                k = FludkRouting.k
                # XXX: remove self it in the list?
                self.kclosest.append(n)
                self.kclosest.sort(
                        lambda a, b: FludkRouting.kCompare(a[2], b[2], key))
                self.kclosest = self.kclosest[:k]

        #for n in self.outstanding:
        #   if n in self.pending:
        #       self.pending.remove(n) # remove anyone we've sent queries to...
        self.pending = list(set(self.pending) - set(self.outstanding))
        for i in self.queried:
            n = (self.queried[i][0], self.queried[i][1], i)
            if n in self.pending:
                self.pending.remove(n) # ...and anyone who has responded.
        
        self.pending.sort(lambda a, b: FludkRouting.kCompare(a[2], b[2], key))

        #print "queried: %s" % str(self.queried)
        #print "outstanding: %s" % str(self.outstanding)
        #print "pending: %s" % str(self.pending)

        return self.decideToContinue(response, key, x)
示例#2
0
 def roundDone(self, responses, key, x):
     #print "done %d:" % x
     #print "roundDone: %s" % responses
     if len(self.pending) != 0 or len(self.outstanding) != 0: 
         # should only get here for nodes that don't accept connections
         # XXX: updatenode -- decrease trust
         for i in self.pending:
             logger.debug("FN: %s couldn't contact node %s (%s:%d)" 
                     % (self.abbrv, fencode(i[2]), i[0], i[1]))
             self.debugpath.append(
                     "FN: %s couldn't contact node %s (%s:%d)" 
                     % (self.abbrv, fencode(i[2]), i[0], i[1]))
             for n in self.kclosest:
                 if (n[0],n[1],n[2]) == i:
                     self.kclosest.remove(n)
     
     logger.info("kFindNode %s terminated successfully after %d queries." 
             % (self.abbrv, len(self.queried)))
     self.debugpath.append("FN: %s terminated successfully after %d queries."
             % (self.abbrv, len(self.queried)))
     self.kclosest.sort(
             lambda a, b: FludkRouting.kCompare(a[2], b[2], key))
     result = {}
     if FludkRouting.k > len(self.kclosest):
         k = len(self.kclosest)
     else:
         k = FludkRouting.k
     result['k'] = self.kclosest[:k]
     #print "result: %s" % result
     #if len(result['k']) > 1:
     #   # if the results (aggregated from multiple responses) contains the
     #   # exact key, just return the correct answer (successful node 
     #   # lookup done).
     #   #print "len(result): %d" % len(result['k'])
     #   #print "result[0][2]: %s %d" % (type(result['k'][0][2]), 
     #   #   result['k'][0][2])
     #   #print "         key: %s %d" % (type(key), key)
     #   if result['k'][0][2] == key:
     #       #print "key matched!"
     #       result['k'] = (result['k'][0],)
     return result