Timeouts

Timeouts은 외부자원에 접근하거나 특정시간을 대기할 경우에 중요하게 사용됩니다.
Go언어에서 Timeoutsselectchannel을 이용해서 쉽고 우아하게 구현할 수 있습니다.

package main

import "fmt"
import "time"

func main() {

    c1 := make(chan string, 1)                // [1]
    go func() {
        time.Sleep(time.Second * 2)
        c1 <- "result 1"
    }()

    select {                                  // [2]
    case res := <-c1:
        fmt.Println(res)
    case <-time.After(time.Second * 1):
        fmt.Println("timeout 1")
    }

    c2 := make(chan string, 1)                // [3]
    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")
    }
}
  1. 예제에서는 c1채널에 2초의 시간을 두고 메세지를 전송하고 있습니다.
  2. select구문을 이용해서 timeout을 구현하고 있습니다. res := <-c1구문은 결과가 정상적으로
    올때 출력하고, <-time.After() 1초 후에는 타임아웃을 발생시키는 문장입니다.
    둘다 채널에서 정상적으로 메세지를 받으면 아무 문제없게 출력하고, 1초 후가 되도록 메세지를
    수신하지 못한다면 timeout 케이스가 작동하게 되는 원리 입니다.
  3. 3초의 timeout값을 설정한 경우 입니다. c2채널에서 정상적으로 메세지를 받으면 출력합니다.

실행하면 다음과 같습니다.

$ go run timeouts.go 
timeout 1
result 2

상기 프로그램을 실해하면 첫번째 작업은 시간제한(timeout)이 발생하고, 두번째 작업은 성공했습니다.
select문을 이용한 시간제한(timeout)기법은 채널 통신중에 자주 사용하는 패턴중 하나입니다.
Go언어에서 채널 통신을 쉽고 강력하게 해주는 것이 바로 이런 기능입니다.

다음장에서는 timer & tickers 예제를 통해서 이 기능에 대해서 설명하겠습니다.