Тайм-аути (Timeouts)|Timeouts
#
// _Тайм-аути_ необхідні програмам, що тісно взаємодіють з
// зовнішніми ресурсами або враховують власний час
// виконання. Завдяки каналам та `select` - робота з
// тайм-аутами в Go - проста і приємна.
package main
import (
"fmt"
"time"
)
func main() {
// Припустимо, в нашому прикладі, ми виконуємо виклик
// кудись "назовні", що поверне результат каналом
// `c1` за 2 секунди.
c1 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c1 <- "результат 1"
}()
// Використання `select` реалізує таймаут, де
// `res := <-c1` чекає на повідомлення і `<-Time.After`
// також чекає (1 секунду), на повідомлення з каналу
// (який сам і створює). Оскільки `select` опрацьовує лише
// перший готовий виклик, переможцем буде `time.After`
// оскільки його виконання займає, лише, 1 секунду, на противагу
// 2-ом секундам виконання повільного запиту "назовні"
// (відповідь з якого очікуємо з `c1`).
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(1 * time.Second):
fmt.Println("таймаут 1")
}
// Якщо ми зробимо тайм-аут трошки довшим (скажімо - 3 секунди),
// ми встигнемо отримати та надрукувати результат каналу `c2`,
// що буде отримано раніше більш довгого тайм-ауту.
c2 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c2 <- "результат 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(3 * time.Second):
fmt.Println("таймаут 2")
}
}
# Running this program shows the first operation timing
# out and the second succeeding.
$ go run timeouts.go
таймаут 1
результат 2