Add more to khashmir's DHT implementation.
authorCameron Dale <camrdale@gmail.com>
Wed, 19 Dec 2007 21:48:25 +0000 (13:48 -0800)
committerCameron Dale <camrdale@gmail.com>
Wed, 19 Dec 2007 21:48:25 +0000 (13:48 -0800)
Still needs a massive rewrite for loading config values properly.

apt-dht.py
apt_dht/apt_dht_conf.py
apt_dht/interfaces.py
apt_dht_Khashmir/DHT.py

index 9684f572eca4b6d1c5fd81dd23b10c5fa074b3a7..c7afe4d3e99b4ad45c5fdb57a76d15aff6ccdc3a 100644 (file)
@@ -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
index 038819e0b4b422797aa803b4aa03fcb5f9aca52f..5d591808ab2435c043db452bb1e6d6b5368ef3e5 100644 (file)
@@ -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',
     
index c6bea9d50b49b8e808c3be93cfacdf8a2a5d1cb1..446cd02f99cc6bb05977d26735537759f81531a3 100644 (file)
@@ -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."""
index 78d913b225767dc581a0326f38101245491430b7..ca5bb609bc38d1ad8a7d86418efb54e088d93d37 100644 (file)
@@ -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)