Ответ
Оба метода пакета context создают контекст, который автоматически отменяется по истечении времени. Ключевое различие — в способе задания этого времени.
-
context.WithTimeout(parent, duration)- Принимает относительный интервал времени (
time.Duration). - Удобен, когда нужно ограничить операцию простым таймаутом: "выполнять не дольше 2 секунд".
// Контекст отменится через 2 секунды после его создания ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() // Важно всегда вызывать cancel() - Принимает относительный интервал времени (
-
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)).
Ответ 18+ 🔞
Так, слушай, вот объясняю про эти контексты в Go, как бабушке на лавочке. Есть два способа заставить твой код не тупить вечность, а вовремя послать всё нахуй.
Первый — context.WithTimeout(parent, duration)
Это как поставить таймер на духовке. Говоришь: «Эй, пирожки, у вас есть ровно две минуты, а потом я вас выкидываю, даже если вы сырые внутри». Передаёшь просто интервал — 2*time.Second. Удобно, быстро, мозги не надо ломать.
// Через две секунды — пиздец, отмена, всем спасибо.
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() // Это, блядь, не забывай, а то память потечёт!
Второй — context.WithDeadline(parent, time)
А это уже планёрка у начальства. Тебе говорят: «К пяти часам, сука, отчёт на столе!». И не важно, сколько времени сейчас — ты должен успеть к конкретному моменту. Передаёшь абсолютное время, time.Time.
// Рассчитываешь этот ебучий дедлайн: сейчас + 2 секунды.
deadline := time.Now().Add(2 * time.Second)
ctx, cancel := context.WithDeadline(context.Background(), deadline)
defer cancel()
Так когда чем пользоваться, ёпта?
WithTimeout— твой ежедневный инструмент, как отвертка. Запрос к базе, вызов API — везде, где нужно просто сказать «больше двух секунд не жду, пошёл нахуй».WithDeadline— когда есть общий, ебаный, сквозной дедлайн на целую цепочку вызовов. Получил его сверху — пробросил вниз, чтобы все дочерние функции тоже знали, что к пяти часам всё летит в тартарары.
И главный секрет, от которого сам отъебешься: внутри WithTimeout — это просто обёртка, которая вызывает WithDeadline, прибавляя к текущему времени твой интервал. Так что, по сути, разница только в том, как тебе удобнее думать: «через сколько» или «к какому часу».
Вот и вся магия, ебать мои старые костыли. Главное — cancel() не забудь, а то будет тебе вечная утечка, хуй потом найдёшь.