def in_reactor(f):
    """decorate a function by running it with maybeDeferred in a reactor"""
    def wrap(*args, **kwargs):
        from twisted.internet import reactor, defer
        result = []

        def _async():
            d = defer.maybeDeferred(f, *args, **kwargs)

            @d.addErrback
            def eb(f):
                f.printTraceback()

            @d.addBoth
            def do_stop(r):
                result.append(r)
                reactor.stop()
        reactor.callWhenRunning(_async)
        reactor.run()
        return result[0]
    wrap.__doc__ = f.__doc__
    wrap.__name__ = f.__name__
    wrap._orig = f  # for tests
    return wrap
decorate a function by running it with maybeDeferred in a reactor