now republishing keys once an hour

This commit is contained in:
Brian Muller 2014-01-19 21:30:36 -05:00
parent 61631b21db
commit 21dc0cca39
2 changed files with 38 additions and 13 deletions

View File

@ -33,9 +33,9 @@ class Server(object):
self.ksize = ksize self.ksize = ksize
self.alpha = alpha self.alpha = alpha
self.log = Logger(system=self) self.log = Logger(system=self)
storage = ForgetfulStorage() self.storage = ForgetfulStorage()
self.node = Node(id or digest(random.getrandbits(255))) self.node = Node(id or digest(random.getrandbits(255)))
self.protocol = KademliaProtocol(self.node, storage, ksize) self.protocol = KademliaProtocol(self.node, self.storage, ksize)
self.refreshLoop = LoopingCall(self.refreshTable).start(3600) self.refreshLoop = LoopingCall(self.refreshTable).start(3600)
def listen(self, port): def listen(self, port):
@ -58,8 +58,16 @@ class Server(object):
nearest = self.protocol.router.findNeighbors(node, self.alpha) nearest = self.protocol.router.findNeighbors(node, self.alpha)
spider = NodeSpiderCrawl(self.protocol, node, nearest) spider = NodeSpiderCrawl(self.protocol, node, nearest)
ds.append(spider.find()) ds.append(spider.find())
def republishKeys(_):
ds = []
# Republish keys older than one hour
for key, value in self.storage.iteritemsOlderThan(3600):
ds.append(self.set(key, value))
return defer.gatherResults(ds) return defer.gatherResults(ds)
return defer.gatherResults(ds).addCallback(republishKeys)
def bootstrappableNeighbors(self): def bootstrappableNeighbors(self):
""" """
Get a C{list} of (ip, port) C{tuple}s suitable for use as an argument Get a C{list} of (ip, port) C{tuple}s suitable for use as an argument

View File

@ -1,11 +1,15 @@
import time import time
from itertools import izip
from itertools import imap
from itertools import takewhile
import operator
from collections import OrderedDict from collections import OrderedDict
class ForgetfulStorage(object): class ForgetfulStorage(object):
def __init__(self, ttl=7200): def __init__(self, ttl=604800):
""" """
By default, max age is 2 hours By default, max age is a week.
""" """
self.data = OrderedDict() self.data = OrderedDict()
self.ttl = ttl self.ttl = ttl
@ -13,22 +17,17 @@ class ForgetfulStorage(object):
def __setitem__(self, key, value): def __setitem__(self, key, value):
if key in self.data: if key in self.data:
del self.data[key] del self.data[key]
self.data[key] = (time.time() + self.ttl, value) self.data[key] = (time.time(), value)
self.cull() self.cull()
def cull(self): def cull(self):
pop = 0 for k, v in self.iteritemsOlderThan(self.ttl):
for value in self.data.itervalues():
if value[0] >= time.time():
break
pop += 1
for _ in xrange(pop):
self.data.popitem(first=True) self.data.popitem(first=True)
def get(self, key, default=None): def get(self, key, default=None):
self.cull() self.cull()
if key in self.data: if key in self.data:
return self.data[key][1] return self[key]
return default return default
def __getitem__(self, key): def __getitem__(self, key):
@ -42,3 +41,21 @@ class ForgetfulStorage(object):
def __repr__(self): def __repr__(self):
self.cull() self.cull()
return repr(self.data) return repr(self.data)
def iteritemsOlderThan(self, secondsOld):
minBirthday = time.time() - secondsOld
zipped = self._tripleIterable()
matches = takewhile(lambda r: minBirthday >= r[1], zipped)
return imap(operator.itemgetter(0, 2), matches)
def _tripleIterable(self):
ikeys = self.data.iterkeys()
ibirthday = imap(operator.itemgetter(0), self.data.itervalues())
ivalues = imap(operator.itemgetter(1), self.data.itervalues())
return izip(ikeys, ibirthday, ivalues)
def iteritems(self):
self.cull()
ikeys = self.data.iterkeys()
ivalues = imap(operator.itemgetter(1), self.data.itervalues())
return izip(ikeys, ivalues)