Python Web & Scripts — Django, FastAPI, скрипты
asyncio ломается не в await, а в границах между I/O, CPU и cancellation
Если в проекте «всё асинхронно», это ещё не значит, что оно масштабируется. В реальности чаще всего путают три вещи: параллельность, конкурентность и неблокирующий I/O. asyncio хорошо работает там, где задачи ждут сеть, диск или таймеры. Как только в корутину попадает тяжёлая CPU-работа, event loop начинает задыхаться.
Есть 4 типовые ошибки:
— забыли вынести CPU-bound кусок в thread/process pool;
— сделали много await подряд там, где нужен gather();
— не закрыли клиент/сессию/соединение и получили утечки;
— игнорируют cancellation, а потом ловят «зависшие» фоновые задачи.
Отдельно проверьте точки входа. Если внутри корутины вызывается обычный блокирующий код — sleep, requests, синхронный ORM, файловые операции без ограничений — весь выигрыш от asyncio исчезает. Для внешних API, очередей и парсинга это особенно заметно: один блокирующий вызов может остановить десятки задач.
Хорошее правило: корутина должна либо ждать I/O, либо быстро делегировать тяжёлую работу наружу. Если это не так — перепишите участок, а не «добавляйте больше async».
9 ·