📝 Python

asyncio: таймауты, отмена задач и graceful shutdown

P
Автор
PyLand Team
📅
Опубликовано
30.06.2026
⏱️
Время чтения
1 мин
👁️
Просмотров
606
🌳
Уровень
Продвинутый

Три вещи которые обязательно нужны в production async коде.

asyncio.timeout() — таймауты без боли (Python 3.11+)

import asyncio

async def slow_operation():
    await asyncio.sleep(10)

async def main():
    try:
        async with asyncio.timeout(3.0):   # 3 секунды максимум
            await slow_operation()
    except TimeoutError:
        print("Превысили таймаут")

До Python 3.11 использовался asyncio.wait_for():

try:
    result = await asyncio.wait_for(slow_operation(), timeout=3.0)
except asyncio.TimeoutError:
    print("Таймаут")

CancelledError — отмена задач

async def worker():
    try:
        while True:
            await do_work()
    except asyncio.CancelledError:
        await cleanup()    # освобождаем ресурсы
        raise              # ВАЖНО: всегда перебрасываем CancelledError

async def main():
    task = asyncio.create_task(worker())
    await asyncio.sleep(5)
    task.cancel()          # отправляем CancelledError в task
    try:
        await task
    except asyncio.CancelledError:
        print("Задача отменена корректно")

Правило: в except CancelledError всегда делай raise. Иначе задача не завершится корректно.

Graceful shutdown — красивое завершение

import asyncio, signal

async def main():
    loop = asyncio.get_running_loop()
    stop = asyncio.Event()

    def handle_signal():
        print("Получен SIGINT, завершаем...")
        stop.set()

    loop.add_signal_handler(signal.SIGINT, handle_signal)
    loop.add_signal_handler(signal.SIGTERM, handle_signal)

    # Основная работа
    tasks = [asyncio.create_task(worker(i)) for i in range(5)]

    await stop.wait()       # ждём сигнала

    # Отменяем все задачи
    for task in tasks:
        task.cancel()

    # Ждём завершения с cleanup
    await asyncio.gather(*tasks, return_exceptions=True)
    print("Завершено чисто")

asyncio.run(main())

return_exceptions=True в gather() важно: без него первый CancelledError прервёт ожидание остальных задач.

Ваша реакция на статью

💬 Комментарии (0)

🔐 Войдите в систему, чтобы оставить комментарий
🚪 Войти
💭

Комментариев пока нет

Станьте первым, кто поделится мнением об этой статье!

🔗 Похожие

Похожие статьи

Продолжите изучение с этими материалами

📝

Event loop в Python: как asyncio создаёт параллел…

Event loop — сердце asyncio. Он не запускает код параллельно в нескольких потоках. Он переключается...

📅 30.06.2026 👁️ 387
📝

run_in_executor и anyio: sync-библиотеки в async …

Иногда нужно вызвать синхронную библиотеку из async кода не блокируя event loop.

📅 30.06.2026 👁️ 366
📝

Async context managers: async with и @asynccontex…

Async context managers управляют ресурсами в async коде — соединениями, файлами, транзакциями.

📅 30.06.2026 👁️ 392
🎓 Продолжить обучение

В каких курсах используется этот материал

Перейдите к курсу, чтобы закрепить материал на практике.

FastAPI: от первого маршрута до AI-сайта Открыть программу курса