context.Context

Тема дорожной карты · Golang

Пакет context — стандартный механизм Go для передачи дедлайнов, сигналов отмены и значений, привязанных к запросу, через границы API и между goroutines. Каждое значение context.Context неизменяемо; новые производные контексты создаются с помощью context.WithCancel, context.WithTimeout, context.WithDeadline или context.WithValue, каждый возвращает дочерний контекст и (где применимо) CancelFunc, который следует вызывать через defer во избежание утечек goroutines. HTTP-серверы на net/http автоматически прикрепляют контекст к каждому входящему запросу (r.Context()), а фреймворки Gin, Echo, Fiber и Chi распространяют его через цепочки обработчиков, чтобы запросы к базе данных, gRPC-вызовы и исходящие HTTP-запросы соблюдали единый дедлайн. Middleware, интегрирующееся со стеком наблюдаемости — трассировки OpenTelemetry, метки Prometheus, структурированное логирование с slog или Zap, — как правило, хранит и извлекает идентификаторы трассировки и метаданные запроса через context.WithValue. Корректное использование пакета context необходимо для создания отзывчивых, не допускающих утечек Golang-сервисов, которые корректно обрабатывают отмену под нагрузкой.

Как это работает

context.Context построен на goroutines (лёгкие green threads, мультиплексируемые на OS-потоки Go-runtime) и channels (типизированные каналы для сообщений между goroutines). go funcName() запускает goroutine; ch <- value шлёт; value := <-ch принимает. select ждёт на нескольких каналах; context.Context несёт cancellation + дедлайны через дерево вызовов. sync.Mutex, sync.WaitGroup, sync.Once, атомарные примитивы, errgroup для группировки goroutines.

Когда применять

Goroutines используйте свободно — дёшевы (~2-4KB stack начально, растёт по нужде). Всегда имейте способ остановить goroutine (cancellation context.Context, close канала, deadline) — утёкшие goroutines = тихий рост памяти. Context первым аргументом — в любую функцию с I/O. sync.Mutex — для shared state, когда channels неудобны. errgroup — для "fan out, wait, первая ошибка пробрасывается".

Типичные ошибки

Ловушки context.Context: утечки goroutines (goroutine ждёт навеки на канале, в который никто не пишет); data race на shared map без mutex (race detector ловит: go test -race); deadlock (go test -race НЕ ловит deadlock — осторожно); не пробрасывают context.Context, и cancellation не доходит до глубокого вызова.

Связанные понятия

Полезные ресурсы