Skip to content

Instantly share code, notes, and snippets.

@dreid
Created March 23, 2012 19:36
Show Gist options
  • Save dreid/2174170 to your computer and use it in GitHub Desktop.
Save dreid/2174170 to your computer and use it in GitHub Desktop.
wrap a deferred in a context manager. Use this to collect timings with scales.
from twisted.internet.defer import maybeDeferred
def withDeferred(contextManager, f, *args, **kwargs):
contextManager.__enter__()
def _exit(result):
contextManager.__exit__(None, None, None)
return result
def _exitEb(failure):
if contextManager.__exit__(
failure.type, failure.value, failure.stack):
return failure
d = maybeDeferred(f, *args, **kwargs)
d.addCallbacks(_exit, _exitEb)
return d
if __name__ == '__main__':
from greplin import scales
from twisted.internet.defer import Deferred
from twisted.internet import reactor
STATS = scales.collection('/my-scales', scales.PmfStat('timing'))
def doStuff(_, arg):
print "bar"
d = Deferred()
if arg < 3:
d.addCallback(doStuff, arg + 1)
reactor.callLater(1, d.callback, True)
return d
def done(_):
print scales.getStats()
def doit():
print "foo"
d2 = withDeferred(STATS.timing.time(), doStuff, None, 0)
d2.addCallback(done)
reactor.callLater(0, doit)
reactor.callLater(2, doit)
reactor.callLater(30, doit)
reactor.callLater(20, doit)
reactor.run()
@erikkaplun
Copy link

I think if contextManager.__exit__ should be if not contextManager.__exit__ as per the doc at http://docs.python.org/2/reference/datamodel.html#object.__exit__:

If an exception is supplied, and the method wishes to suppress the exception (i.e., prevent it from being propagated), it should return a true value.

@erikkaplun
Copy link

...and failure.stack should be failure.getTracebackObject()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment