【问题标题】:Calling Tornado Coroutine from asyncio从 asyncio 调用 Tornado 协程
【发布时间】:2020-10-16 06:38:02
【问题描述】:

我的主事件循环使用 asyncio,但需要调用一个库方法,该方法是 tornado.concurrent.Future 类型的协程。尝试在协程上等待失败,RuntimeError

RuntimeError: Task got bad yield: <tornado.concurrent.Future object at 0x7f374abdbef0>

文档和搜索建议升级 Tornado 的版本(当前使用 4.5)或使用方法 tornado.platform.asyncio.to_asyncio_future,它不再产生 RuntimeError,而是挂在 await 上。我很想知道是否有人可以解释发生了什么。主要有两种方法,一种是异步调用 Tornado 协程,另一种是纯 Tornado,按预期工作。

import asyncio
from tornado import gen
from tornado.platform.asyncio import to_asyncio_future


async def coro_wrap():
    tornado_fut = coro()
    
    print(f'tornado_fut = {tornado_fut}, type({type(tornado_fut)})')
    
    async_fut = to_asyncio_future(tornado_fut)
    print(f'async_fut = {async_fut}')
               
    res = await async_fut
    print(f'done => {res}')


@gen.coroutine
def coro():
    print('coro start')
    yield gen.sleep(3)
    print('coro end')    
    return 'my result'


def main():    
    loop = asyncio.get_event_loop()
    
    task = loop.create_task(coro_wrap())    
    loop.run_until_complete(task)
    
    print('end')
    
    
def main2():
    from tornado import ioloop
    loop = ioloop.IOLoop()
    res = loop.run_sync(coro)
    print(res)


if __name__ == '__main__':
    main()

主输出

coro start
tornado_fut = <tornado.concurrent.Future object at 0x7f41493f1f28>, type(<class 'tornado.concurrent.Future'>)
async_fut = <Future pending>

ma​​in2 的输出

coro start
coro end
my result

【问题讨论】:

  • yield gen.sleep(3) 应该是 yield from gen.sleep(3)。更好的是,尝试将coro 定义为async def,删除装饰器,然后只使用await gen.sleep(3)
  • @user4815162342 协程装饰器应用于库函数。如果我可以重写函数,我就不会问这个问题了。

标签: python python-asyncio tornado coroutine


【解决方案1】:

在新版本的 Tornado 中,这很有效。

在旧版本的龙卷风中,您必须同时使用 to_asyncio_future 和在启动时调用 tornado.platform.asyncio.AsyncIOMainLoop.install()

【讨论】:

    猜你喜欢
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    相关资源
    最近更新 更多