运行时警告:协程从未在单独的线程中等待 asyncio.run

时间:2021-06-16 00:52:34

标签: python python-asyncio python-multithreading

我已经构建了一个基于 aiohttp 的小蜘蛛。这是一些缩写代码:

import asyncio
from aiohttp import ClientSession
from threading import Thread

class Spider:
    def __init__(self, urls):
        self.urls = urls
        self.start()

    async def fetch(self, session, url):
        async with session.get(url) as response:
            await self.handle_status(response) # undefined here for brevity
            return await self.render_body(response) # undefined here for brevity

    async def process_urls(self):
        async with ClientSession() as session:
            tasks = {self.fetch(session, url) for url in self.urls}
            for task in asyncio.as_completed(tasks):
                raw_data = await task
                data = self.extract_data(*raw_data) # sync method undefined here for brevity
                await self.store_data(data) # undefined here for brevity

    def start(self) -> None:
        try:
            asyncio.run(self.process_urls())
        except RuntimeError:  # loop already running
            x = Thread(target=asyncio.run, args=(self.process_urls(),))
            x.start()
            x.join()

start 方法旨在启动一个 asyncio 循环,但如果已经在运行,则它会在新线程中启动一个新循环。

无论是否从现有循环运行,代码都有效。但是如果从现有循环运行(例如使用 pytest.mark.asyncio()),我会收到此警告:

<块引用>

RuntimeWarning: coroutine 'Spider.process_urls' 从未被等待 x.join()

这个警告是我应该关注的吗?

有没有更好的方法来处理这个不会导致这个警告的?

我试过 loop = asyncio.get_running_loop() 和 loop.create_task(self.process_urls()) 而不是创建一个新线程,但是失败了:

<块引用>

运行时错误:协程忽略了 GeneratorExit

我尝试过 nest-asyncio,但我的主要用例涉及另一个使用 uvloop 的库,因此 nest-asyncio 不兼容。

0 个答案:

没有答案