Есть ли Pythonic способ запуска асинхронной задачи в фоновом режиме, похожий на использование contextmanager? - PullRequest
0 голосов
/ 04 сентября 2018

Недавно я хотел запускать некоторые асинхронные задачи в фоновом режиме при выполнении других задач, но я не думал, что кода было Pythonic достаточно:

task = asyncio.create_task(long_task())
await short_task()
await task

Итак, я сделал это больше Pythonic :

@asynccontextmanager
async def run_in_background(coro):
    task = asyncio.create_task(coro)
    yield task
    await task


async def main():
    async with run_in_background(long_task()):
        await short_task()

Что-то подобное уже существует? Если нет, то считается ли это более Pythonic или менее Pythonic, чем существующий способ?

1 Ответ

0 голосов
/ 04 сентября 2018

Что-то подобное уже существует?

Не сейчас, но это очень полезная идея. Более общая версия концепции будет добавлена ​​в Python 3.8 в форме класса TaskGroup, созданного на основе предшествующего уровня техники в Curio и Trio .

Я бы предложил расширить реализацию, чтобы использовать finally, предоставляя гарантию того, что фоновая задача будет ожидаться даже в случае исключения; например:

@asynccontextmanager
async def run_in_background(coro):
    task = asyncio.create_task(coro)
    try:
        yield task
    finally:
        await task

Если нет, то считается ли это более питонским или менее питонским, чем существующий способ?

Эта часть вопроса, очевидно, основана на мнении, но я бы сказал, что менеджер контекста более Pythonic, потому что он гарантирует , что фоновая задача выполнена и ожидается к тому времени, когда блок оставлен. Это также гарантирует, что исключения в фоновой задаче не будут передаваться без вывода сообщений , что является частым источником ошибок в асинхронном коде.

...