Наиболее надёжен последний вариант с учётом области состояния: атомарная операция Redis для нескольких workers либо asyncio.Lock для одного event loop. Проверка и уменьшение должны составлять одну критическую операцию.
В AsyncIO нужно атомарно уменьшить лимит в общем состоянии после await. Какой подход наиболее надёжен?
Наиболее надёжен последний вариант с учётом области состояния: атомарная операция Redis для нескольких workers либо asyncio.Lock для одного event loop. Проверка и уменьшение должны составлять одну критическую операцию.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В AsyncIO нужно атомарно уменьшить лимит в общем состоянии после await. Какой подход наиболее надёжен?
- Увеличить число воркеров FastAPI.
- Проверить лимит до await и надеяться на редкие коллизии.
- Убрать await из обработчика.
- Использовать asyncio.Lock и измерить ожидание блокировки под нагрузкой.
- Повторять операцию при ошибке без изменения модели состояния.
- Перенести операцию в атомарную команду Redis или защитить критическую секцию asyncio.Lock.
Ответ
Наиболее надёжен последний вариант с учётом области состояния: атомарная операция Redis для нескольких workers либо asyncio.Lock для одного event loop. Проверка и уменьшение должны составлять одну критическую операцию.
Если чтение лимита сделано до await, другой запрос может изменить его во время ожидания. Под lock нужно заново проверить актуальное значение и выполнить изменение, а не только присваивание устаревшего результата. В Redis простого DECR недостаточно, если нельзя уйти ниже нуля: нужен атомарный условный переход. Дополнительные workers увеличивают конкуренцию. Измерение ожидания lock полезно для производительности, но само по себе не создаёт корректности.