context.WithTimeout — контекст с автоматической отменой через заданное время:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel() // обязательно, даже если таймаут сработает сам
result, err := fetchData(ctx)
if err != nil {
if ctx.Err() == context.DeadlineExceeded {
log.Println("timeout!")
}
return err
}
Использование в HTTP-запросе:
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
resp, err := client.Do(req) // отменится через 3 секунды
context.WithDeadline — то же самое, но принимает абсолютное время (time.Time), а не длительность.
Дочерний контекст не может продлить таймаут родителя:
parent, _ := context.WithTimeout(ctx, 2*time.Second)
child, _ := context.WithTimeout(parent, 10*time.Second) // реально 2с, не 10