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

Состояние в экземпляре middleware

Вопрос

Middleware записывает self.current_user = request.user в __call__, а сервисы читают middleware.current_user. Чем это плохо?

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

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

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

Коротко

Правильный ответ: Экземпляр общий для запросов: при потоках или async пользователи перепутаются. Middleware создаётся один раз на процесс, и в многопоточном воркере (gthread, ASGI) несколько запросов идут одновременно: один перезапишет пользователя другого.

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

  1. Экземпляр общий для запросов: при потоках или async пользователи перепутаютсяправильный ответ
  2. Django запрещает атрибуты у middleware и выбросит ошибку при первом запросе
  3. Это замедляет каждый запрос в разы, потому что атрибут копируется в каждый поток
  4. Ничем: это стандартный приём, так устроен request.user в самом Django

Разбор

Middleware создаётся один раз на процесс, и в многопоточном воркере (gthread, ASGI) несколько запросов идут одновременно: один перезапишет пользователя другого. Это утечка данных. Передавайте пользователя явно или, если нужен неявный контекст, используйте contextvars, которые изолированы между потоками и задачами asyncio.

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

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