【发布时间】:2013-10-16 06:36:39
【问题描述】:
我正在进行的项目都是用 Tornado 编写的,但我包含了一些 Twisted 来处理异步 XML-RPC。我想知道您是否可以将 Tornado 的 gen.engine 和 yield gen.Task 与 Twisted 的代码一起使用。这可能吗?如果是这样,语法会是什么样子?提前致谢。
【问题讨论】:
标签: python asynchronous client-server twisted tornado
我正在进行的项目都是用 Tornado 编写的,但我包含了一些 Twisted 来处理异步 XML-RPC。我想知道您是否可以将 Tornado 的 gen.engine 和 yield gen.Task 与 Twisted 的代码一起使用。这可能吗?如果是这样,语法会是什么样子?提前致谢。
【问题讨论】:
标签: python asynchronous client-server twisted tornado
当然 - 但它在 Twisted 中称为 inlineCallbacks:
from twisted.internet.defer import inlineCallbacks
@inlineCallbacks
def foo():
x = yield bar()
print x
【讨论】:
您可以将gen.Task 与任何带有callback 关键字参数的东西一起使用。然而,Twisted 风格的代码通常返回一个Deferred 而不是将回调作为输入。您需要将Deferred 包装在tornado.gen 可以理解的内容中(可能是Future)。像这样的东西(未经测试):
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())
【讨论】:
为了正确设置异常,我稍微修改了 Ben 的示例代码。
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 异常作为 failure.Failure。 future.set_exception 抱怨它不是异常类型。
【讨论】: