WithDeadline и WithValue
Абсолютные крайние сроки и передача значений в области запроса
«WithDeadline и WithValue» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
context.WithDeadline
WithDeadline создаёт контекст, который отменяется в определённый момент времени. Если у родительского контекста уже установлен более ранний крайний срок, приоритет имеет срок родительского контекста.
deadline := time.Now().Add(10 * time.Second)
ctx, cancel := context.WithDeadline(parent, deadline)
defer cancel()WithTimeout и WithDeadline
WithTimeout(parent, d) эквивалентен WithDeadline(parent, time.Now().Add(d)). Используйте WithDeadline, когда у Вас есть абсолютный момент истечения срока действия, например из входящего заголовка RPC.
Чтение крайнего срока
Проверяйте крайний срок любого контекста с помощью ctx.Deadline(). Логическое значение указывает, существует ли крайний срок.
if deadline, ok := ctx.Deadline(); ok {
fmt.Println("expires at:", deadline)
}context.WithValue
WithValue добавляет в контекст пару «ключ—значение». Код на последующих этапах извлекает её с помощью ctx.Value(key).
type ctxKey string
const userKey ctxKey = "user"
ctx := context.WithValue(parent, userKey, currentUser)
func getUser(ctx context.Context) *User {
u, _ := ctx.Value(userKey).(*User)
return u
}Предотвращение конфликтов ключей
Используйте неэкспортируемый тип, специфичный для пакета, в качестве ключей, чтобы предотвратить конфликты между пакетами. Никогда не используйте встроенные типы (string, int) напрямую как ключи контекста.
// Bad: string key can collide
ctx = context.WithValue(ctx, "user", u)
// Good: package-scoped type
type userKeyType struct{}
ctx = context.WithValue(ctx, userKeyType{}, u)Что хранить в контексте
Храните только значения, относящиеся к области действия запроса и пересекающие границы API: идентификаторы трассировки, токены Auth, идентификаторы запросов. Не храните необязательные аргументы функций или изменяемое состояние.
Производительность WithValue
ctx.Value выполняет линейный поиск вверх по цепочке контекстов. Избегайте хранения большого количества значений в одном контексте; несколько значений объединяйте в одной структуре.
type RequestMeta struct {
UserID int
TraceID string
}
type metaKey struct{}
ctx = context.WithValue(ctx, metaKey{}, RequestMeta{...})Передача значений через промежуточное ПО
Промежуточное ПО HTTP — стандартное место для добавления метаданных запроса в контекст и их извлечения в обработчиках:
func Auth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user := authenticate(r)
ctx := context.WithValue(r.Context(), userKey, user)
next.ServeHTTP(w, r.WithContext(ctx))
})
}r.WithContext
Заменяйте контекст HTTP-запроса с помощью r.WithContext(ctx). Это создаёт поверхностную копию запроса с новым контекстом, не изменяя исходный.
Передача крайнего срока
Когда шлюз задаёт крайний срок в контексте и передаёт запрос дальше, все службы, принимающие этот контекст, автоматически соблюдают крайний срок без явной логики тайм-аута.
Цепочка контекстов
Каждый WithValue, WithCancel или WithTimeout оборачивает родительский контекст в новый узел. ctx.Value проходит по цепочке, пока не найдёт ключ или не достигнет корневого контекста, возвращающего nil.
Быстрая проверка
Почему ключи контекста должны быть неэкспортируемыми типами, специфичными для пакета?
Итоги: WithDeadline и WithValue
Основные положения:
- WithDeadline отменяет контекст в абсолютный момент времени, а WithTimeout задаёт относительный срок
- ctx.Deadline() считывает крайний срок
- Используйте WithValue для метаданных, относящихся к области действия запроса, и типизированные неэкспортируемые ключи
- Объединяйте несколько значений в структуре, чтобы уменьшить глубину цепочки
Часто задаваемые вопросы
Урок «WithDeadline и WithValue» бесплатный?
Да — полный текст урока «WithDeadline и WithValue» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «WithDeadline и WithValue»?
Абсолютные крайние сроки и передача значений в области запроса Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «WithDeadline и WithValue»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Зачем нужен context.Context
- WithCancel и WithTimeout
- WithDeadline и WithValue
- Контекст в HTTP- и вызовах к базе данных