The project I am working on is all written in Tornado, but I have included a bit of Twisted to deal with asynchronous XML-RPC. I was wondering if you can use Tornado\'s gen.engi
Sure - but it's called inlineCallbacks
in Twisted:
from twisted.internet.defer import inlineCallbacks
@inlineCallbacks
def foo():
x = yield bar()
print x
You can use gen.Task
with anything that takes a callback
keyword argument. However, Twisted-style code usually returns a Deferred
instead of taking a callback as input. You'll need to wrap the Deferred
in something tornado.gen
can understand (probably a Future
). Something like this (untested):
def wrap_deferred(deferred):
# Could also use concurrent.futures.Future from the standard library,
# but Tornado's version gives better tracebacks on python 2.
future = tornado.concurrent.TracebackFuture()
deferred.addCallbacks(future.set_result, future.set_exception)
return future
@gen.coroutine
def my_coroutine(self):
# Use wrap_deferred instead of gen.Task
x = yield wrap_deferred(some_twisted_function())
I modified Ben's sample code a bit in order to set exception correctly.
def wrap_deferred(deferred):
future = tornado.concurrent.TracebackFuture()
deferred.addCallback(future.set_result)
deferred.addErrback(lambda err: future.set_exception(err.value))
return future
twisted wrap exception as a failure.Failure. future.set_exception complains it is not an exception type.