from bsddb3 import db ## find this at http://pybsddb.sf.net/
from bsddb3._db import DBNotFoundError
+from xmlrpclib import Binary
+
# don't ping unless it's been at least this many seconds since we've heard from a peer
MAX_PING_INTERVAL = 60 * 15 # fifteen minutes
class Khashmir(xmlrpc.XMLRPC):
__slots__ = ['listener', 'node', 'table', 'store', 'itime', 'kw', 'app']
def __init__(self, host, port):
- self.node = Node(newID(), host, port)
+ self.node = Node().init(newID(), host, port)
self.table = KTable(self.node)
self.app = Application("xmlrpc")
self.app.listenTCP(port, server.Site(self))
"""
ping this node and add the contact info to the table on pong!
"""
- n =Node(" "*20, host, port) # note, we
+ n =Node().init(" "*20, host, port) # note, we
self.sendPing(n)
def valueForKey(self, key, callback):
""" returns the values found for key in global table """
nodes = self.table.findNodes(key)
+ # decode values, they will be base64 encoded
# create our search state
state = GetValue(self, key, callback)
reactor.callFromThread(state.goWithNodes, nodes)
def _notStaleNodeHandler(sender, old=old):
""" called when we get a ping from the remote node """
- if sender['id'] == old.id:
+ sender = Node().initWithSenderDict(sender)
+ if sender.id == old.id:
self.table.insertNode(old)
df = old.ping(self.node.senderDict())
df = node.ping(self.node.senderDict())
## these are the callbacks we use when we issue a PING
def _pongHandler(sender, id=node.id, host=node.host, port=node.port, table=self.table):
- if id != 20 * ' ' and id != sender['id']:
+ sender = Node().initWithSenderDict(sender)
+ if id != 20 * ' ' and id != sender.id:
# whoah, got response from different peer than we were expecting
pass
else:
#print "Got PONG from %s at %s:%s" % (`msg['id']`, t.target.host, t.target.port)
- n = Node(sender['id'], host, port)
+ sender['host'] = host
+ sender['port'] = port
+ n = Node().initWithDict(sender)
table.insertNode(n)
return
def _defaultPong(err):
returns sender dict
"""
ip = self.crequest.getClientIP()
- n = Node(sender['id'], ip, sender['port'])
+ sender['host'] = ip
+ n = Node().initWithDict(sender)
self.insertNode(n)
return self.node.senderDict()
nodes = self.table.findNodes(target)
nodes = map(lambda node: node.senderDict(), nodes)
ip = self.crequest.getClientIP()
- n = Node(sender['id'], ip, sender['port'])
+ sender['host'] = ip
+ n = Node().initWithDict(sender)
self.insertNode(n)
return nodes, self.node.senderDict()
def xmlrpc_store_value(self, key, value, sender):
- h1 = sha(key+value).digest()
+ key = key.data
+ h1 = sha(key+value.data).digest()
t = `time.time()`
if not self.store.has_key(h1):
- v = dumps((key, value, t))
+ v = dumps((key, value.data, t))
self.store.put(h1, v)
self.itime.put(t, h1)
self.kw.put(key, h1)
self.itime.put(t, h1)
ip = self.crequest.getClientIP()
- n = Node(sender['id'], ip, sender['port'])
+ sender['host'] = ip
+ n = Node().initWithDict(sender)
self.insertNode(n)
return self.node.senderDict()
def xmlrpc_find_value(self, key, sender):
ip = self.crequest.getClientIP()
- n = Node(sender['id'], ip, sender['port'])
+ key = key.data
+ sender['host'] = ip
+ n = Node().initWithDict(sender)
self.insertNode(n)
+
if self.kw.has_key(key):
c = self.kw.cursor()
tup = c.set(key)
v = loads(self.store[h1])[1]
l.append(v)
tup = c.next()
+ l = map(lambda v: Binary(v), l)
return {'values' : l}, self.node.senderDict()
else:
nodes = self.table.findNodes(key)
#------ testing
-def test_build_net(quiet=0, peers=8, pause=1):
+def test_build_net(quiet=0, peers=24, host='localhost', pause=1):
from whrandom import randrange
import thread
port = 2001
print "Building %s peer table." % peers
for i in xrange(peers):
- a = Khashmir('localhost', port + i)
+ a = Khashmir(host, port + i)
l.append(a)
for peer in l[1:]:
n = l[randrange(0, len(l))].node
- peer.addContact(n.host, n.port)
+ peer.addContact(host, n.port)
n = l[randrange(0, len(l))].node
- peer.addContact(n.host, n.port)
+ peer.addContact(host, n.port)
n = l[randrange(0, len(l))].node
- peer.addContact(n.host, n.port)
+ peer.addContact(host, n.port)
if pause:
time.sleep(.30)
a = l[randrange(0,n)]
b = l[randrange(0,n)]
- def callback(nodes, flag=flag):
- if (len(nodes) >0) and (nodes[0].id == b.node.id):
+ def callback(nodes, flag=flag, id = b.node.id):
+ if (len(nodes) >0) and (nodes[0].id == id):
print "test_find_nodes PASSED"
else:
print "test_find_nodes FAILED"