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)
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