remove deferral.sleep's canceller, as it wasn't used anywhere and caused incompatibil...
[p2pool.git] / p2pool / util / deferral.py
index 868649b..6f75b76 100644 (file)
@@ -1,6 +1,8 @@
 from __future__ import division
 
 import itertools
+import random
+import sys
 
 from twisted.internet import defer, reactor
 from twisted.python import failure, log
@@ -10,10 +12,20 @@ def sleep(t):
     reactor.callLater(t, d.callback, None)
     return d
 
+def run_repeatedly(f, *args, **kwargs):
+    current_dc = [None]
+    def step():
+        delay = f(*args, **kwargs)
+        current_dc[0] = reactor.callLater(delay, step)
+    step()
+    def stop():
+        current_dc[0].cancel()
+    return stop
+
 class RetrySilentlyException(Exception):
     pass
 
-def retry(message='Error:', delay=3, max_retries=None):
+def retry(message='Error:', delay=3, max_retries=None, traceback=True):
     '''
     @retry('Error getting block:', 1)
     @defer.inlineCallbacks
@@ -31,7 +43,10 @@ def retry(message='Error:', delay=3, max_retries=None):
                     if i == max_retries:
                         raise
                     if not isinstance(e, RetrySilentlyException):
-                        log.err(None, message)
+                        if traceback:
+                            log.err(None, message)
+                        else:
+                            print >>sys.stderr, message, e
                     yield sleep(delay)
                 else:
                     defer.returnValue(result)
@@ -149,25 +164,22 @@ class DeferredCacher(object):
     
     _nothing = object()
     def call_now(self, key, default=_nothing):
-        if key in self.waiting:
-            if default is not self._nothing:
-                return default
-            raise NotNowError(key)
-        
         if key in self.backing:
             return self.backing[key]
-        else:
+        if key not in self.waiting:
             self.waiting[key] = defer.Deferred()
             def cb(value):
                 self.backing[key] = value
                 self.waiting.pop(key).callback(None)
             def eb(fail):
                 self.waiting.pop(key).callback(None)
+                if fail.check(RetrySilentlyException):
+                    return
                 print
                 print 'Error when requesting noncached value:'
                 fail.printTraceback()
                 print
             self.func(key).addCallback(cb).addErrback(eb)
-            if default is not self._nothing:
-                return default
-            raise NotNowError(key)
+        if default is not self._nothing:
+            return default
+        raise NotNowError(key)