📝 Python

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

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

Три вещи которые обязательно нужны в 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 👁️ 125
📝

pytest-django: тестирование Django

Охватываемые темы: Установка, @pytest.mark.djangodb, Фикстуры, Тестирование views.

📅 30.06.2026 👁️ 133
📝

pip: менеджер пакетов Python

Охватываемые темы: Установка пакетов, Обновление и удаление, requirements.txt, Виртуальное окружение.

📅 30.06.2026 👁️ 120

Понравилась статья?

Подпишитесь на наши обновления и получайте новые статьи первыми. Развивайтесь вместе с PyLand!