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.engine and yield gen.Task with Twisted's code. Is this possible? If so how would the syntax look like? Thanks in advance.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
Sure - but it's called inlineCallbacks
in Twisted:
from twisted.internet.defer import inlineCallbacks
@inlineCallbacks
def foo():
x = yield bar()
print x
回答2:
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())
回答3:
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.