Timeouts

Timeouts->타임아웃 #

// _Timeouts_은 외부 리소스를 연결하거나 실행 시간을 제한해야하는 프로그램에서 중요합니다.
//  Go에서 타임아웃 구현은 채널과 `select`를 사용하면 쉽고 우아하게 할 수 있습니다.
package main

import "time"
import "fmt"

func main() {

	// 이번 예제에선, 2초 후에 `c1` 채널에 결괏값을 반환하는 외부 호출을 실행한다고 가정합니다.
	c1 := make(chan string, 1)
	go func() {
		time.Sleep(time.Second * 2)
		c1 <- "result 1"
	}()

	// 다음은 `select`로 구현한 타임아웃입니다.
	//  `res := <-c1`은 결괏값을 대기하고 `<-Time.After`는 1초의 타임아웃 후에 전달되는 값을 대기합니다.
	//  `select`는 대기중인 첫번째 리시브로 진행되고 있기 때문에, 만약 이 연산이 허용된 1초 보다 더 오래걸릴 경우, 타임아웃이 발생합니다.
	select {
	case res := <-c1:
		fmt.Println(res)
	case <-time.After(time.Second * 1):
		fmt.Println("timeout 1")
	}

	// 만약 타움아웃을 3초로 늘리면, `c2`로부터의 수신은 성공하고 결괏값을 출력할겁니다.
	c2 := make(chan string, 1)
	go func() {
		time.Sleep(time.Second * 2)
		c2 <- "result 2"
	}()
	select {
	case res := <-c2:
		fmt.Println(res)
	case <-time.After(time.Second * 3):
		fmt.Println("timeout 2")
	}
}
# 이 프로그램을 실행하면 첫 연산은 타임아웃되고 두번째 연산은 성공하는걸 볼 수 있습니다.
$ go run timeouts.go 
timeout 1
result 2

# `select` 타임아웃 패턴을 사용하려면 채널을 통해 결괏값을 전달해야합니다.
#  Go의 중요한 기능들이 채널과 `select` 기반이기 때문에 일반적으로 이는 좋은 아이디어입니다.
#  다음에 타이머(timers)와 티커(tickers)에 대한 두 가지 예제를 살펴보겠습니다.