В чем разница между context.WithTimeout и context.WithDeadline?

Ответ

Оба метода пакета context создают контекст, который автоматически отменяется по истечении времени. Ключевое различие — в способе задания этого времени.

  1. context.WithTimeout(parent, duration)

    • Принимает относительный интервал времени (time.Duration).
    • Удобен, когда нужно ограничить операцию простым таймаутом: "выполнять не дольше 2 секунд".
    // Контекст отменится через 2 секунды после его создания
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel() // Важно всегда вызывать cancel()
  2. context.WithDeadline(parent, time)

    • Принимает абсолютный момент времени (time.Time).
    • Идеален, когда есть общий дедлайн для цепочки операций: "все дочерние операции должны завершиться к 17:00".
    // Рассчитываем дедлайн: сейчас + 2 секунды
    deadline := time.Now().Add(2 * time.Second)
    ctx, cancel := context.WithDeadline(context.Background(), deadline)
    defer cancel()

Когда что использовать?

  • WithTimeout — самый частый выбор для простых таймаутов (HTTP-запросы, запросы к БД).
  • WithDeadline — полезен при пробрасывании общего дедлайна через несколько сервисов или функций. Если функция получает контекст с дедлайном, она может использовать его для своих дочерних операций.

Важный момент: под капотом context.WithTimeout(parent, duration) является просто удобной обёрткой и вызывает context.WithDeadline(parent, time.Now().Add(duration)).