AsyncLocalStorage для контекста запроса
Вопрос
Нужно, чтобы каждая строка лога внутри обработки запроса содержала requestId, не передавая его аргументом через все функции. Какой механизм Node для этого предназначен?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Глобальная переменная, которую middleware перезаписывает на каждом запросе
process.env.REQUEST_ID, который middleware выставляет перед обработчикомworker_threads: отдельный поток на запрос со своими глобальнымиAsyncLocalStorageизnode:async_hooks: контекст переживает awaitправильный ответ
Разбор
AsyncLocalStorage.run(store, fn) делает store доступным через getStore() во всём, что асинхронно порождено из fn, включая продолжения после await. На этом построены трейсинг OpenTelemetry, контекст в pino-http, nestjs-cls. Стабилен и широко используется.
Глобальная переменная и process.env общие для всех одновременных запросов: при конкурентной обработке запрос A запишет id, запрос B перезапишет, и логи A получат чужой id. Поток на запрос в Node это дорого и бессмысленно для I/O-нагрузки.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.