From 445f3b8084171babfb68e89441927c055eb9bf6f Mon Sep 17 00:00:00 2001 From: Cameron Dale Date: Wed, 19 Dec 2007 13:48:25 -0800 Subject: [PATCH] Add more to khashmir's DHT implementation. Still needs a massive rewrite for loading config values properly. --- apt-dht.py | 2 ++ apt_dht/apt_dht_conf.py | 4 ++++ apt_dht/interfaces.py | 20 +++++++++------- apt_dht_Khashmir/DHT.py | 52 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/apt-dht.py b/apt-dht.py index 9684f57..c7afe4d 100644 --- a/apt-dht.py +++ b/apt-dht.py @@ -57,6 +57,8 @@ service.IProcess(application).processName = 'apt-dht' DHT = __import__(config.get('DEFAULT', 'DHT'), globals(), locals(), ['DHT']) assert(IDHT.implementedBy(DHT.DHT), "You must provide a DHT implementation that implements the IDHT interface.") myDHT = DHT.DHT() +myDHT.loadConfig(config) +myDHT.join() if not config.getboolean('DEFAULT', 'DHT-only'): from apt_dht.apt_dht import AptDHT diff --git a/apt_dht/apt_dht_conf.py b/apt_dht/apt_dht_conf.py index 038819e..5d59180 100644 --- a/apt_dht/apt_dht_conf.py +++ b/apt_dht/apt_dht_conf.py @@ -38,6 +38,10 @@ DEFAULTS = { } DHT_DEFAULTS = { + # bootstrap nodes to contact to join the DHT + 'bootstrap': """www.camrdale.org:9977 + steveholt.hopto.org:9977""", + # magic id to use before we know a peer's id 'NULL_ID': 20 * '\0', diff --git a/apt_dht/interfaces.py b/apt_dht/interfaces.py index c6bea9d..446cd02 100644 --- a/apt_dht/interfaces.py +++ b/apt_dht/interfaces.py @@ -9,31 +9,33 @@ from zope.interface import Interface class IDHT(Interface): """An abstract interface for using a DHT implementation.""" - def loadConfig(self, config): + def loadConfig(self, config, section): """Load the DHTs configuration from a dictionary. - @type config: C{dictionary} + @type config: C{SafeConfigParser} @param config: the dictionary of config values """ - def join(self, bootstrap_nodes): + def join(self): """Bootstrap the new DHT node into the DHT. - @type bootstrap_nodes: C{list} of (C{string}, C{int}) - @param bootstrap_nodes: a list of the nodes to contact to join the DHT - @rtype: C{Deffered} + @rtype: C{Deferred} @return: a deferred that will fire when the node has joined """ def leave(self): """Depart gracefully from the DHT. - @rtype: C{Deffered} - @return: a deferred that will fire when the node has joined + @rtype: C{Deferred} + @return: a deferred that will fire when the node has left """ def getValue(self, key): - """Get a value from the DHT for the specified key.""" + """Get a value from the DHT for the specified key. + + @rtype: C{Deferred} + @return: a deferred that will fire with the stored values + """ def storeValue(self, key, value): """Store a value in the DHT for the specified key.""" diff --git a/apt_dht_Khashmir/DHT.py b/apt_dht_Khashmir/DHT.py index 78d913b..ca5bb60 100644 --- a/apt_dht_Khashmir/DHT.py +++ b/apt_dht_Khashmir/DHT.py @@ -1,11 +1,61 @@ +from twisted.internet import defer from zope.interface import implements from apt_dht.interfaces import IDHT +from khashmir import Khashmir + +class DHTError(Exception): + """Represents errors that occur in the DHT.""" class DHT: implements(IDHT) def __init__(self): - pass \ No newline at end of file + self.config = None + + def loadConfig(self, config, section): + """See L{apt_dht.interfaces.IDHT}.""" + self.config = config + self.section = section + if self.config.has_option(section, 'port'): + self.port = self.config.get(section, 'port') + else: + self.port = self.config.get('DEFAULT', 'port') + + def join(self): + """See L{apt_dht.interfaces.IDHT}.""" + if self.config is None: + raise DHTError, "configuration not loaded" + + self.khashmir = Khashmir('', self.port) + + for node in self.config.get(self.section, 'bootstrap'): + host, port = node.rsplit(':', 1) + self.khashmir.addContact(host, port) + + self.khashmir.findCloseNodes() + + def leave(self): + """See L{apt_dht.interfaces.IDHT}.""" + if self.config is None: + raise DHTError, "configuration not loaded" + + self.khashmir.listenport.stopListening() + + def getValue(self, key): + """See L{apt_dht.interfaces.IDHT}.""" + if self.config is None: + raise DHTError, "configuration not loaded" + + d = defer.Deferred() + self.khashmir.valueForKey(key, d.callback) + return d + + def storeValue(self, key, value): + """See L{apt_dht.interfaces.IDHT}.""" + if self.config is None: + raise DHTError, "configuration not loaded" + + self.khashmir.storeValueForKey(key, value) -- 2.39.2