Added the number of times each action was started to the DHT stats.
authorCameron Dale <camrdale@gmail.com>
Mon, 17 Mar 2008 22:21:26 +0000 (15:21 -0700)
committerCameron Dale <camrdale@gmail.com>
Mon, 17 Mar 2008 22:21:26 +0000 (15:21 -0700)
apt_p2p_Khashmir/DHT.py
apt_p2p_Khashmir/actions.py
apt_p2p_Khashmir/khashmir.py
apt_p2p_Khashmir/stats.py

index d0a40ee..e9baaa8 100644 (file)
@@ -289,7 +289,7 @@ class DHT:
                 if stat['group'] != 'Actions':
                     out.write("<tr><th>Statistic</th><th>Value</th></tr>\n")
                 else:
-                    out.write("<tr><th>Action</th><th>Sent</th><th>OK</th><th>Failed</th><th>Received</th><th>Error</th></tr>\n")
+                    out.write("<tr><th>Action</th><th>Started</th><th>Sent</th><th>OK</th><th>Failed</th><th>Received</th><th>Error</th></tr>\n")
                 old_group = stat['group']
             if stat['group'] != 'Actions':
                 out.write("<tr title='" + stat['tip'] + "'><td>" + stat['desc'] + '</td><td>' + str(stat['value']) + '</td></tr>\n')
@@ -298,7 +298,7 @@ class DHT:
                 actions.sort()
                 for action in actions:
                     out.write("<tr><td>" + action + "</td>")
-                    for i in xrange(5):
+                    for i in xrange(6):
                         out.write("<td>" + str(stat['value'][action][i]) + "</td>")
                     out.write('</tr>\n')
                     
index 1179713..3863f9a 100644 (file)
@@ -49,7 +49,7 @@ class ActionBase:
     @ivar sort: used to sort nodes by their proximity to the target
     """
     
-    def __init__(self, caller, target, callback, config, action, num_results = None):
+    def __init__(self, caller, target, callback, config, stats, action, num_results = None):
         """Initialize the action.
         
         @type caller: L{khashmir.Khashmir}
@@ -60,6 +60,8 @@ class ActionBase:
         @param callback: the method to call with the results
         @type config: C{dictionary}
         @param config: the configuration variables for the DHT
+        @type stats: L{stats.StatsLogger}
+        @param stats: the statistics gatherer
         @type action: C{string}
         @param action: the name of the action to call on remote nodes
         @type num_results: C{int}
@@ -72,6 +74,7 @@ class ActionBase:
         self.target = target
         self.config = config
         self.action = action
+        stats.startedAction(action)
         self.num = intify(target)
         self.queried = {}
         self.answered = {}
@@ -233,8 +236,8 @@ class ActionBase:
 class FindNode(ActionBase):
     """Find the closest nodes to the key."""
 
-    def __init__(self, caller, target, callback, config, action="findNode"):
-        ActionBase.__init__(self, caller, target, callback, config, action)
+    def __init__(self, caller, target, callback, config, stats, action="findNode"):
+        ActionBase.__init__(self, caller, target, callback, config, stats, action)
 
     def processResponse(self, dict):
         """Save the token received from each node."""
@@ -251,8 +254,8 @@ class FindNode(ActionBase):
 class FindValue(ActionBase):
     """Find the closest nodes to the key and check for values."""
 
-    def __init__(self, caller, target, callback, config, action="findValue"):
-        ActionBase.__init__(self, caller, target, callback, config, action)
+    def __init__(self, caller, target, callback, config, stats, action="findValue"):
+        ActionBase.__init__(self, caller, target, callback, config, stats, action)
 
     def processResponse(self, dict):
         """Save the number of values each node has."""
@@ -269,13 +272,13 @@ class FindValue(ActionBase):
 class GetValue(ActionBase):
     """Retrieve values from a list of nodes."""
     
-    def __init__(self, caller, target, local_results, num_results, callback, config, action="getValue"):
+    def __init__(self, caller, target, local_results, num_results, callback, config, stats, action="getValue"):
         """Initialize the action with the locally available results.
         
         @type local_results: C{list} of C{string}
         @param local_results: the values that were available in this node
         """
-        ActionBase.__init__(self, caller, target, callback, config, action, num_results)
+        ActionBase.__init__(self, caller, target, callback, config, stats, action, num_results)
         if local_results:
             for result in local_results:
                 self.results[result] = 1
@@ -318,13 +321,13 @@ class GetValue(ActionBase):
 class StoreValue(ActionBase):
     """Store a value in a list of nodes."""
 
-    def __init__(self, caller, target, value, num_results, callback, config, action="storeValue"):
+    def __init__(self, caller, target, value, num_results, callback, config, stats, action="storeValue"):
         """Initialize the action with the value to store.
         
         @type value: C{string}
         @param value: the value to store in the nodes
         """
-        ActionBase.__init__(self, caller, target, callback, config, action, num_results)
+        ActionBase.__init__(self, caller, target, callback, config, stats, action, num_results)
         self.value = value
         
     def getNodesToProcess(self):
index 6734ff7..48a0c0c 100644 (file)
@@ -185,7 +185,7 @@ class KhashmirBase(protocol.Factory):
             d.callback(nodes)
         else:
             # Start the finding nodes action
-            state = FindNode(self, id, d.callback, self.config)
+            state = FindNode(self, id, d.callback, self.config, self.stats)
             reactor.callLater(0, state.goWithNodes, nodes)
     
     def insertNode(self, node, contacted = True):
@@ -219,6 +219,7 @@ class KhashmirBase(protocol.Factory):
                     self.table.justSeenNode(old.id)
             
             # Bucket is full, check to see if old node is still available
+            self.stats.startedAction('ping')
             df = old.ping(self.node.id)
             df.addCallbacks(_notStaleNodeHandler, _staleNodeHandler)
 
@@ -251,6 +252,7 @@ class KhashmirBase(protocol.Factory):
             elif callback:
                 callback(None)
         
+        self.stats.startedAction('join')
         df = node.join(self.node.id)
         df.addCallbacks(_pongHandler, _defaultPong)
 
@@ -374,7 +376,7 @@ class KhashmirRead(KhashmirBase):
             d.addCallback(callback)
 
         # Search for others starting with the locally found ones
-        state = FindValue(self, key, d.callback, self.config)
+        state = FindValue(self, key, d.callback, self.config, self.stats)
         reactor.callLater(0, state.goWithNodes, nodes)
 
     def valueForKey(self, key, callback, searchlocal = True):
@@ -401,7 +403,7 @@ class KhashmirRead(KhashmirBase):
 
         def _getValueForKey(nodes, key=key, local_values=l, response=callback, self=self):
             """Use the found nodes to send requests for values to."""
-            state = GetValue(self, key, local_values, self.config['RETRIEVE_VALUES'], response, self.config)
+            state = GetValue(self, key, local_values, self.config['RETRIEVE_VALUES'], response, self.config, self.stats)
             reactor.callLater(0, state.goWithNodes, nodes)
             
         # First lookup nodes that have values for the key
@@ -478,7 +480,7 @@ class KhashmirWrite(KhashmirRead):
                     """Default callback that does nothing."""
                     pass
                 response = _storedValueHandler
-            action = StoreValue(self, key, value, self.config['STORE_REDUNDANCY'], response, self.config)
+            action = StoreValue(self, key, value, self.config['STORE_REDUNDANCY'], response, self.config, self.stats)
             reactor.callLater(0, action.goWithNodes, nodes)
             
         # First find the K closest nodes to operate on.
index d1d5ff1..e2752dd 100644 (file)
@@ -196,14 +196,23 @@ class StatsLogger:
                 
         return stats
     
+    #{ Called by the action
+    def startedAction(self, action):
+        """Record that an action was started.
+        
+        @param action: the name of the action
+        """
+        act = self.actions.setdefault(action, [0, 0, 0, 0, 0, 0])
+        act[0] += 1
+    
     #{ Called by the transport
     def sentAction(self, action):
         """Record that an action was attempted.
         
         @param action: the name of the action
         """
-        act = self.actions.setdefault(action, [0, 0, 0, 0, 0])
-        act[0] += 1
+        act = self.actions.setdefault(action, [0, 0, 0, 0, 0, 0])
+        act[1] += 1
         
     def responseAction(self, response, action):
         """Record that a response to an action was received.
@@ -212,8 +221,8 @@ class StatsLogger:
         @param action: the name of the action
         @return: the response (for use in deferreds)
         """
-        act = self.actions.setdefault(action, [0, 0, 0, 0, 0])
-        act[1] += 1
+        act = self.actions.setdefault(action, [0, 0, 0, 0, 0, 0])
+        act[2] += 1
         return response
         
     def failedAction(self, response, action):
@@ -223,8 +232,8 @@ class StatsLogger:
         @param action: the name of the action
         @return: the response (for use in deferreds)
         """
-        act = self.actions.setdefault(action, [0, 0, 0, 0, 0])
-        act[2] += 1
+        act = self.actions.setdefault(action, [0, 0, 0, 0, 0, 0])
+        act[3] += 1
         return response
         
     def receivedAction(self, action):
@@ -233,16 +242,16 @@ class StatsLogger:
         @param action: the name of the action
         """
         self.reachable = True
-        act = self.actions.setdefault(action, [0, 0, 0, 0, 0])
-        act[3] += 1
+        act = self.actions.setdefault(action, [0, 0, 0, 0, 0, 0])
+        act[4] += 1
     
     def errorAction(self, action):
         """Record that a received action resulted in an error.
         
         @param action: the name of the action
         """
-        act = self.actions.setdefault(action, [0, 0, 0, 0, 0])
-        act[4] += 1
+        act = self.actions.setdefault(action, [0, 0, 0, 0, 0, 0])
+        act[5] += 1
     
     def sentBytes(self, bytes):
         """Record that a single packet of some bytes was sent.