Skip to content

Instantly share code, notes, and snippets.

@sporsh
Created November 2, 2012 02:24
Show Gist options
  • Save sporsh/3998312 to your computer and use it in GitHub Desktop.
Save sporsh/3998312 to your computer and use it in GitHub Desktop.
from twisted.internet import defer
import threading
import Queue
from twisted.python import failure
def blocking_call_from_thread(reactor, f, *args, **kwargs):
"""Calls a twisted function from a thread and blocks until
the deferred has called back.
If the function did not return a deferred, raise an exception.
"""
queue = Queue.Queue()
def _callFromThread():
deferred = f(*args, **kwargs)
if not isinstance(deferred, defer.Deferred):
raise Exception("%r does not return a deferred" % f)
deferred.addBoth(queue.put)
return deferred
reactor.callFromThread(_callFromThread)
result = queue.get()
if isinstance(result, failure.Failure):
result.raiseException()
return result
def make_blocking(f):
"""Makes a twisted function synchronious by waiting on it's deferred
"""
def wrapper(*args, **kwargs):
from twisted.internet import reactor
return blocking_call_from_thread(reactor, f, *args, **kwargs)
return wrapper
class TwistedProxy(object):
def make_blocking(self, f):
return lambda *a, **kwa: blocking_call_from_thread(self.reactor,
f, *a, **kwa)
def __getattr__(self, name):
attr = getattr(object, name)
if callable(attr):
return make_blocking(attr)
elif isinstance(attr, self.__class__):
return attr
else:
return attr
@make_blocking
def delayed_function():
from twisted.internet import reactor
d = defer.Deferred()
reactor.callLater(5, d.callback, 'RESULT')
return d
@make_blocking
def blatti():
import time
print 'fooooo'
time.sleep(3)
return 'BOOO'
def reactor_thread():
from twisted.internet import reactor
print "starting reactor..."
reactor.run(installSignalHandlers=False)
print "reactor stopped."
thread = threading.Thread(target=reactor_thread)
thread.start()
if __name__ == '__main__':
from twisted.internet import reactor
print "before function"
print delayed_function()
print "after function"
print blatti()
reactor.callFromThread(reactor.stop)
print "reactor stopped"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment