Дедлайн - момент, после которого ответ больше не нужен. Он передаётся по цепочке вызовов и уменьшается на каждом шаге.
На клиенте
ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
defer cancel()
order, err := client.GetOrder(ctx, request)
Если предыдущий этап потратил 300 мс, следующий получает уже не 500, а оставшиеся 200. Поэтому дедлайны не перемножаются.
Сервис B получает только оставшиеся 200 мс, а не новые 500. Общий дедлайн включает работу всех предыдущих шагов.
Сервер проверяет ctx.Done() на длительных операциях и возвращает DeadlineExceeded или соответствующую ошибку контекста.
Отмена
Клиентская отмена закрывает поток и доходит до сервера. Это не гарантирует мгновенную остановку: репозиторий, HTTP-клиент и фоновые задачи должны принимать тот же контекст.
context.Background() внутри обработчика обрывает цепочку, поэтому его не используют для новых сетевых вызовов.
Metadata
Metadata похожа на HTTP-заголовки:
md := metadata.New(map[string]string{"authorization": "Bearer " + token, "x-request-id": requestID})
ctx = metadata.NewOutgoingContext(ctx, md)
Сервер читает metadata.FromIncomingContext(ctx). Туда кладут токен и request ID, а не большие бизнес-объекты. Значения секретов не пишут в логи.
Где заканчивается ожидание
После DeadlineExceeded нельзя продолжать работу как ни в чём не бывало. Сетевой вызов уже отменён, а вот собственные горутины и записи в базу надо остановить отдельно через тот же ctx. Иначе клиент ушёл, а сервер продолжает тратить ресурсы и может записать результат, который никто не ждёт.
Ключи metadata пишут строчными ASCII-буквами: authorization, x-request-id. Не кладут туда nil, объекты Go и данные с произвольной кодировкой; для бинарных значений есть ключи с суффиксом -bin.
Если токен нужен только внутри одного метода, не сохраняют его в долгоживущем контексте или глобальной переменной. Передают по вызову, а логи с metadata перед записью очищают от секретов.
Коротко
- Дедлайн распространяется по цепочке и уменьшается на каждом шаге.
- Отмена доезжает только через явно переданный контекст.
- Metadata передаёт токен и корреляцию, не полезную нагрузку.
- Секреты в metadata не логируются.