Материал проходит вычитку — возможны неточности.
Урок 107 из 118

Зачем нужен context

Клиент «ФинГура» закрыл вкладку на середине загрузки большого архива, а «Полка» продолжала лить файлы в S3: горели CPU и сеть. Аня на разборе сформулировала правило: отмена — сигнал, на который код отвечает сам.

Главная мысль

context — это сигнал отмены и дедлайна, который передаётся сквозь слои программы; отмена кооперативна: каждый слой сам слушает сигнал в своих блокирующих точках.

Сигнал сквозь слои

func handle(ctx context.Context, ch <-chan int) {
    for {
        select {
        case <-ctx.Done():
            return // клиент ушёл, дальше работать незачем
        case v := <-ch:
            process(v) // каждая блокирующая точка слушает отмену
        }
    }
}

context.Context — интерфейс с методом Done <-chan struct{}. Канал закрывается, когда контекст отменяют — по таймауту, по отмене или по дедлайну. Главная идея: контекст передаётся от верхнего уровня вниз, и каждый слой может слушать один и тот же сигнал. Отмена кооперативна: ctx.Done нужно проверять в select при каждой блокирующей точке. Разовая проверка в начале не работает — если клиент ушёл, пока код «работает», горутина об этом не узнает.

Зачем это нужно

Представь обработчик HTTP-запроса: он зовёт сервис, тот — репозиторий, репозиторий — базу. Если клиент оборвал соединение на полпути, работа всей цепочки стала бессмысленной. Без контекста нижние слои об этом не знают и досчитывают впустую — тратят CPU, держат соединения. С контекстом сигнал «клиент ушёл» доходит до каждого слоя, и все сворачиваются.

Где контекст обязателен

Сетевые и блокирующие операции: запросы к БД, HTTP-вызовы, чтение из каналов. Для них контекст — штатный способ передать сигнал, на который вызов обязан отреагировать сам: драйвер БД и HTTP-клиент слушают ctx и возвращают ошибку при отмене, а голое чтение из канала контекст не прерывает — там нужен select. Вспомни (утечки) и (таймаут и отмена): контекст — штатное лекарство от обеих проблем.

В следующем уроке

Вы узнаете:

  • почему контекст передают первым аргументом
  • что даёт context.Context как интерфейс
Задание · вопросы

Проверьте себя

Вопрос 1 из 3

Почему «досчитать впустую» отменённый запрос дорого?

Вопрос 2 из 3

Что даёт context поверх голого done-канала?

Вопрос 3 из 3

Что значит «отмена кооперативна»?

Итоги

Context — общий сигнал отмены, передаваемый вниз по слоям; отмена кооперативна, и слушать сигнал нужно в каждой блокирующей точке, а не один раз. Без контекста нижние слои не знают, что их работа больше не нужна.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки