Python Web & Scripts — Django, FastAPI, скрипты
asyncio ломается не там, где «медленно», а там, где его кормят блокировками
За неделю в репах чаще всего всплывают одни и те же ошибки:
— внутри корутины вызывают тяжелый sync-код: requests, ORM без async, файловые операции;
— забывают про лимиты параллелизма и запускают сотни задач через gather без контроля;
— держат один общий client/session и не закрывают его;
— ловят исключения только в одной задаче, а остальные тихо падают.
Если есть I/O, используй await до конца цепочки. Если попался синхронный кусок, выноси его в thread pool или отдельный процесс. Иначе event loop начинает обслуживать не задачи, а ожидание чужих блокировок.
Для контроля нагрузки нужны семафоры, очереди и явные таймауты. Без них asyncio легко превращается в генератор случайных зависаний: внешняя API отвечает медленно, а у тебя уже забиты все воркеры и растет хвост из висящих задач.
Еще одна типовая ошибка — отсутствие отмены и cleanup. Task cancelled не должен оставлять открытые соединения, незакрытые файлы и полумертвые записи в БД. Лучше один раз написать аккуратный finally, чем потом искать утечки по логам.
Главное правило: asyncio ускоряет только то, что умеет ждать. Все остальное он просто делает более заметным.
3 ·