Timeouts

Тайм-аути (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