Функция context.WithTimeout
Функция context.WithTimeout создает новый контекст
с таймаутом. Она принимает родительский контекст и
продолжительность времени, после которого контекст
будет автоматически отменен. Функция возвращает
новый контекст и функцию отмены. Если таймаут
истекает, контекст завершается с ошибкой
context.DeadlineExceeded.
Синтаксис
ctx, cancel := context.WithTimeout(parent, timeout)
defer cancel()
Первый параметр parent — родительский контекст,
от которого наследуется новый контекст. Второй параметр
timeout — время в наносекундах, через которое
контекст будет отменен. Возвращаемое значение —
новый контекст и функция для ручной отмены.
Пример использования с таймаутом
Давайте создадим контекст с таймаутом в 1 секунду и выполним операцию, которая занимает больше времени:
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
select {
case <-time.After(2 * time.Second):
fmt.Println("operation completed")
case <-ctx.Done():
fmt.Println(ctx.Err())
}
}
Результат выполнения кода:
"context deadline exceeded"
В этом примере контекст отменяется через 1 секунду, поэтому операция не успевает завершиться и выводится ошибка превышения времени.
Пример с успешным завершением
Теперь давайте выполним операцию, которая укладывается в установленный таймаут:
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
select {
case <-time.After(1 * time.Second):
fmt.Println("operation completed")
case <-ctx.Done():
fmt.Println(ctx.Err())
}
}
Результат выполнения кода:
"operation completed"
Здесь операция выполняется за 1 секунду, что меньше таймаута в 2 секунды, поэтому программа успешно завершается.
Пример с ручной отменой
Функцию отмены можно вызвать явно до истечения таймаута:
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
go func() {
time.Sleep(500 * time.Millisecond)
cancel()
}()
select {
case <-time.After(2 * time.Second):
fmt.Println("operation completed")
case <-ctx.Done():
fmt.Println(ctx.Err())
}
}
Результат выполнения кода:
"context canceled"
В этом примере функция отмены вызывается через 500 мс, поэтому контекст отменяется раньше таймаута.
Смотрите также
-
функцию
context.WithDeadline,
которая отменяет контекст в конкретный момент времени -
функцию
context.WithCancel,
которая создает контекст с ручной отменой -
функцию
context.Background,
которая создает пустой корневой контекст -
функцию
context.WithTimeoutCause,
которая позволяет указать причину отмены