From f8a57c788517d02cb9f5173afea5f2ba8d87adef Mon Sep 17 00:00:00 2001
From: aum <aum>
Date: Sun, 15 Aug 2004 13:49:27 +0000
Subject: [PATCH] Pulled another n bugs

---
 apps/stasher/python/scripts/stasher    |   6 +
 apps/stasher/python/scripts/stasher.py |   6 +
 apps/stasher/python/src/stasher.py     | 184 ++++++++++++++++++++++---
 3 files changed, 174 insertions(+), 22 deletions(-)

diff --git a/apps/stasher/python/scripts/stasher b/apps/stasher/python/scripts/stasher
index 9a6f67b311..601cfee4ed 100644
--- a/apps/stasher/python/scripts/stasher
+++ b/apps/stasher/python/scripts/stasher
@@ -1,4 +1,10 @@
 #! /usr/bin/env python
 # wrapper script to run stasher node
+
+# set this to the directory where you've installed stasher
+stasherDir = "/path/to/my/stasher/dir"
+
+import sys
+sys.path.append(stasherDir)
 import stasher
 stasher.main()
diff --git a/apps/stasher/python/scripts/stasher.py b/apps/stasher/python/scripts/stasher.py
index 76b3aa26a8..3f404e5119 100644
--- a/apps/stasher/python/scripts/stasher.py
+++ b/apps/stasher/python/scripts/stasher.py
@@ -1,3 +1,9 @@
 # wrapper script to run stasher node
+
+# set this to the directory where you've installed stasher
+stasherDir = "/path/to/my/stasher/dir"
+
+import sys
+sys.path.append(stasherDir)
 import stasher
 stasher.main()
diff --git a/apps/stasher/python/src/stasher.py b/apps/stasher/python/src/stasher.py
index 8d75331356..489214280a 100644
--- a/apps/stasher/python/src/stasher.py
+++ b/apps/stasher/python/src/stasher.py
@@ -3,17 +3,18 @@
 #@+node:@file stasher.py
 #@@first
 """
-Indroduction:
-    - A simple implementation of the
-      U{Kademlia<http://www.infoanarchy.org/wiki/wiki.pl?Kademlia>}
-      P2P distributed storage and retrieval protocol, designed to
-      utilise the U{I2P<http://www.i2p.net>} stealth network as its transport.
+A simple implementation of the
+U{Kademlia<http://www.infoanarchy.org/wiki/wiki.pl?Kademlia>}
+P2P distributed storage and retrieval protocol, designed to
+utilise the U{I2P<http://www.i2p.net>} stealth network as its transport.
 
-I strongly recommend that when editing this file, you use the Leo
-outlining and literate programming editor - http://leo.sf.net
-
-If Leo doesn't agree with your religion, please try to leave the markups intact
+Most application developers will only need to know about the L{KNode} class
 """
+
+# I strongly recommend that when editing this file, you use the Leo
+# outlining and literate programming editor - http://leo.sf.net
+# If Leo doesn't agree with your religion, please try to leave the markups intact
+
 #@+others
 #@+node:explanatory comments
 #@+at
@@ -162,10 +163,10 @@ runCore = True
 
 # timeouts - calibrate as needed
 timeout = {
-    'ping' : 60,
-    'findNode' : 60,
-    'findData' : 60,
-    'store' : 60,
+    'ping' : 120,
+    'findNode' : 120,
+    'findData' : 120,
+    'store' : 120,
     }
 
 logToSocket = None
@@ -190,7 +191,7 @@ else:
 # client progs from creating 2 nodes of the same name
 _nodes = {}
 
-version = "0.0"
+version = "0.0.1"
 
 #@-node:globals
 #@+node:Exceptions
@@ -262,7 +263,7 @@ class KCore(KBase):
     These threads start up when the first node in this process is created,
     and stop when the last node ceases to exist.
 
-    Upon first import, the L{kademlia} module creates one instance of this
+    Upon first import, the L{stasher} module creates one instance of this
     class. Upon creation, L{KNode} objects register themselves with this core.
     """
     #@    @+others
@@ -1001,8 +1002,8 @@ class KPeer(KBase):
     #@+node:__str__
     def __str__(self):
     
-        return "<KPeer:%s=>0x%s...>" % (
-            self.node.name, ("%x" % self.id.value)[:8])
+        return "<KPeer:%s=>0x%s... dest %s...>" % (
+            self.node.name, ("%x" % self.id.value)[:8], self.dest[:8])
     
     #@-node:__str__
     #@+node:__repr__
@@ -1878,7 +1879,7 @@ class KRpcFindNode(KRpc):
         else:
             self.log(3, "no peer recs???")
             for peerRec in self.peerTab:
-                self.log(4, "%s state=%s" % (peerRec, peerRec.state))
+                self.log(4, "%s state=%s, dest=%s..." % (peerRec, peerRec.state, peerRec.dest[:12]))
     
     #@-node:sendSomeQueries
     #@+node:sendOneQuery
@@ -2381,6 +2382,95 @@ class KRpcStore(KRpc):
     #@-others
 #@-node:class KRpcStore
 #@-node:STORE
+#@+node:PINGALL
+#@+node:class KRpcPingAll
+class KRpcPingAll(KRpc):
+    """
+    Pings all peers
+    """
+    #@    @+others
+    #@+node:attribs
+    type = 'pingall'
+    #@-node:attribs
+    #@+node:__init__
+    def __init__(self, localNode, client=None, **kw):
+        """
+        Creates and launches a PINGALL rpc
+    
+        Arguments:
+            - localNode - the node performing this RPC
+            - client - see KRpc.__init__
+    
+        Keywords: none
+        """
+        if kw.has_key('cbArgs'):
+            KRpc.__init__(self, localNode, client, cbArgs=kw['cbArgs'])
+        else:
+            KRpc.__init__(self, localNode, client)
+    
+    #@-node:__init__
+    #@+node:start
+    def start(self):
+        """
+        Kicks off this RPC
+        """
+        # launch a findNode rpc against each of our peers
+        peers = self.localNode.peers
+        self.numSent = self.numPending = len(peers)
+        self.numReplied = self.numFailed = 0
+        for peer in peers:
+            KRpcPing(self.localNode, self.on_reply, peer=peer)
+        return
+    
+    #@-node:start
+    #@+node:on_reply
+    def on_reply(self, result):
+        """
+        callback which fires when we get a reply from a STORE we sent to a
+        peer
+        """
+        log(3, "got %s" % repr(result))
+    
+        if result:
+            self.numReplied += 1
+        else:
+            self.numFailed += 1
+        self.numPending -= 1
+    
+        if self.numPending <= 0:
+            res = "pinged:%s replied:%s timeout:%s" % (
+                    self.numSent, self.numReplied, self.numFailed)
+            self.log(3, res)
+            self.returnValue(res)
+    
+    #@-node:on_reply
+    #@+node:on_tick
+    def on_tick(self):
+    
+        self.log(3, "this shouldn't have happened")
+        self.returnValue(False)
+    
+    #@-node:on_tick
+    #@+node:returnValue
+    def returnValue(self, result):
+        """
+        an override with a nicer call sig
+        """
+        # a hack for testing - save this RPC object into the node
+        # so we can introspect it
+        self.localNode.lastrpc = self
+    
+        try:
+            KRpc.returnValue(self, result, status=result)
+        except:
+            traceback.print_exc()
+            self.log(3, "Failed to return %s" % repr(result))
+            KRpc.returnValue(self, 0, status=0)
+    
+    #@-node:returnValue
+    #@-others
+#@-node:class KRpcPingAll
+#@-node:PINGALL
 #@-node:RPC Classes
 #@+node:Node Socket Server
 #@+node:class KNodeServer
@@ -2499,6 +2589,12 @@ class KNodeReqHandler(KBase, SocketServer.StreamRequestHandler):
             finish()
             return
     
+        elif cmd == 'pingall':
+            res = node._pingall()
+            write(res+"\n")
+            finish()
+            return
+    
         elif cmd == "die":
             server.isRunning = False
             write("server terminated\n")
@@ -2659,6 +2755,22 @@ class KNodeClient(KBase):
             return None
     
     #@-node:getref
+    #@+node:pingall
+    def pingall(self):
+        """
+        Uplifts node's own ref
+        """
+        self.connect()
+        self.write("pingall\n")
+        self.flush()
+        
+        res = self.readline().strip()
+    
+        self.close()
+    
+        return res
+    
+    #@-node:pingall
     #@+node:kill
     def kill(self):
         """
@@ -2705,6 +2817,7 @@ class KNode(KBase):
         - L{stop} - stops the node
         - L{get} - retrieve a key value
         - L{put} - stores a key value
+        - L{addref} - imports a noderef
 
     This class implements a single kademlia node.
     Within a single process, you can create as many nodes as you like.
@@ -2977,6 +3090,18 @@ class KNode(KBase):
             return KRpcPing(self, peer=peer).execute()
     
     #@-node:_ping
+    #@+node:_pingall
+    def _pingall(self, callback=None):
+        """
+        Sends a ping to all peers, returns text string on replies/failures
+        """
+        if callback:
+            KRpcPingAll(self, callback, **kw)
+        else:
+            return KRpcPingAll(self).execute()
+    
+       
+    #@-node:_pingall
     #@+node:_findnode
     def _findnode(self, something=None, callback=None, **kw):
         """
@@ -3715,8 +3840,11 @@ def usage(detailed=False, ret=0):
     print "  getref <file>"
     print "    - uplifts the running node's dest as base64, writing it to file"
     print "      <file> if given, or to stdout"
-    print "  status"
-    print "    - do a status dump - connectivity, stats etc"
+    print "  hello"
+    print "    - checks that local node is running"
+    print "  pingall"
+    print "    - diagnostic tool - pings all peers, waits for replies or timeouts,"
+    print "      reports results"
     print "  help"
     print "    - display this help"
     print
@@ -3743,6 +3871,7 @@ def main():
                                    "h?vV:S:C:sd:f",
                                    ['help', 'version', 'samaddr=', 'clientaddr=',
                                     'verbosity=', 'status', 'datadir=', 'foreground',
+                                    'shortversion',
                                     ])
     except:
         traceback.print_exc(file=sys.stdout)
@@ -3780,6 +3909,11 @@ def main():
         elif opt in ['-d', '--datadir']:
             dataDir = val
 
+        elif opt == '--shortversion':
+            sys.stdout.write("%s" % version)
+            sys.stdout.flush()
+            sys.exit(0)
+
     #print "Debug - bailing"
     #print repr(opts)
     #print repr(args)
@@ -3796,7 +3930,8 @@ def main():
     #print "cmd=%s, args=%s" % (repr(cmd), repr(args))
     
     if cmd not in ['help', '_start', 'start', 'stop',
-                   'hello', 'get', 'put', 'addref', 'getref']:
+                   'hello', 'get', 'put', 'addref', 'getref',
+                   'pingall']:
         err("Illegal command '%s'" % cmd)
         usage(0, 1)
 
@@ -3994,7 +4129,12 @@ def main():
             outfile.close()
             sys.exit(0)
 
-
+    elif cmd == 'pingall':
+        if logVerbosity > 2:
+            print "Pinging all peers, waiting %s seconds for results" % timeout['ping']
+        res = client.pingall()
+        print res
+        sys.exit(0)
 
 #@-node:main
 #@-others
-- 
GitLab