Выбор ответа Senior Django: устройство обновлено

Контекст запроса в async Django

Вопрос

Нужно, чтобы request_id был доступен в логах из любого места кода при обработке запроса, включая async-вьюхи. Что выбрать для хранения?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: contextvars.ContextVar из middleware. ContextVar изолирован и между потоками, и между задачами asyncio, и корректно копируется при synctoasync/asynctosync. threading.local в async-коде смешает значения разных запросов, обслуживаемых одним потоком цикла событий.

Варианты ответа

  1. threading.local() в middleware
  2. contextvars.ContextVar из middlewareправильный ответ
  3. Глобальную переменную модуля logging_ctx
  4. Атрибут экземпляра middleware self.request_id

Разбор

ContextVar изолирован и между потоками, и между задачами asyncio, и корректно копируется при sync_to_async/async_to_sync. threading.local в async-коде смешает значения разных запросов, обслуживаемых одним потоком цикла событий. Глобальная переменная и атрибут общего экземпляра middleware перезаписываются параллельными запросами.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.