asyncio: длительные задачи с задержкой запуска - PullRequest
0 голосов
/ 17 сентября 2018

Я бы хотел улучшить текущую рабочую ситуацию более элегантно, если она есть.

Мне нужно запустить ряд длительных параллельных задач, некоторые из которых начинаются с задержкой.

Пока что я использую gather и создал небольшую функцию-обертку, которая оборачивает задачу после asyncio.sleep

Обёртка выглядит следующим образом:

async def wrapper(delay, cb, *args, **kwargs):
    await asyncio.sleep(delay)
    return cb(*args, **kwargs)

А в основной функции:

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
    immediate_coroutine(),
    wrapper(2.0, wrapped_coroutine)
))

Я обнаружил, что call_later может быть полезным, но он не ожидает асинхронную функцию в качестве своего обратного вызова.

Есть ли лучший способ обработки задач с помощью asyncio для таких случаев задержки запуска?

1 Ответ

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

Последняя строка wrapper должна содержать await : return await cb(*args, **kwargs).

Есть ли лучший способ обработки задач с асинхронностью для таких случаев задержки запуска?

С исправленной выше ошибкой, это примерно то, что вы должны делать.Возможная область для улучшения заключается в том, что wrapper не нужно принимать обратный вызов и аргументы, он может принимать объект сопрограммы (или любой другой, действительно ожидаемый).Это безопасно, потому что сопрограммы не запускаются при вызове функции сопрограммы, а только когда цикл событий управляет результирующим объектом.

Результирующий API несколько проще и ближе к тем, что предоставляется asyncio:

async def wrapper(delay, coro):
    await asyncio.sleep(delay)
    return await coro

Использование:

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
    immediate_coroutine(),
    wrapper(2.0, wrapped_coroutine())
))
...