Тайм-ауты (Timeouts)|Timeouts
#
// _Тайм-ауты_ важны для программ, которые подключаются
// к внешним ресурсам или которым необходимо ограничить
// время выполнения. Тайм-ауты в Go реализуются легко
// и элегантно благодаря каналам и `select`'ам.
package main
import (
"fmt"
"time"
)
func main() {
// В нашем примере предположим, что мы выполняем внешний
// вызов, который возвращает результат на канале `c1`
// через 2с. Обратите внимание, что канал буферизован,
// поэтому отправка в goroutine неблокирующая. Это
// обычная схема предотвращения утечек горутин в случае,
// если канал никогда не читается.ё
c1 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c1 <- "result 1"
}()
// Вот `select`, реализующий тайм-аут. `res := <-c1`
// ожидает результата, а `<-Time.After` ожидает
// значения, которое будет отправлено после истечения
// времени ожидания 1с. Поскольку `select` продолжает
// работу с первым полученным запросом, мы возьмем
// тайм-аут, если операция займет больше разрешенных 1с.
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(1 * time.Second):
fmt.Println("timeout 1")
}
// Если мы допустим время ожидания более 3с, то
// получение от `c2` будет успешным, и мы распечатаем
// результат.
c2 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c2 <- "result 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(3 * time.Second):
fmt.Println("timeout 2")
}
}
# Запуск этой программы показывает время ожидания
# первой и второй успешной операции.
$ go run timeouts.go
timeout 1
result 2