🐾   [Golang] context.WithTimeout과 context.WithDeadline

  • context.WithTimeout과 context.WithDeadline는 내부는 똑같다. 하지만 의미적으로 차이가 있다.
  • 둘 다 특정 시간이 되면 취소된다.
  • context.WithTimeout과 context.WithDeadline는 취소 함수 (WithCancel)의 리턴값이 같다.

내부

func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {
return c, func() { c.cancel(true, Canceled) }
}

func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
return WithDeadline(parent, time.Now().Add(timeout))
}
  • 내부는 똑같다.
  • 둘 다 특정 시간이 되면 취소되는 context이다

context.WithTimeout

  • 특정 시간이 지나면 종료
  • 10초 후에 종료
func StudyWithTimeout() {
ctx := context.Background()
startTime := time.Now()
fmt.Println("시작 시간: ", startTime)

timeoutCtx, _ := context.WithTimeout(ctx, time.Second*10) // 10초 후에 종료
fmt.Println(timeoutCtx)                                   // 여기 나온 시간에 종료 된다.

//10초 후에 타임 아웃 캔슬을 받는다.
for {
    select {
            case <-timeoutCtx.Done():
            fmt.Println("종료 시간 : ", time.Now())
            return
        }
    }
}

결과

시작 시간: 2022-11-01 21:53:23.844242 +0900 KST m=+0.000070959
context.Background.WithDeadline(2022-11-01 21:53:33.844353 +0900 KST m=+10.000182168 [9.999986875s])
종료 시간 : 2022-11-01 21:53:33.845413 +0900 KST m=+10.001343793

context.WithDeadline

  • 특정 시간이 되면 종료
  • 예시) 22시 02분이 되면 종료
func StudyWithDeadline() {
ctx := context.Background()
startTime := time.Now()
fmt.Println("시작 시간: ", startTime)

deadline, _ := context.WithDeadline(ctx, time.Date(2022, 11, 01, 22, 2, 00, 00, time.Local))
//2022년 11월 01일 22시 2분 00초 로컬 시간에 도달하면 종료

fmt.Println(deadline) // 여기 나온 시간에 종료 된다.

//지정한 날짜에 도달하면 캔슬을 받는다.
for {
select {
case <-deadline.Done():
fmt.Println("종료 신호")
fmt.Println("종료 시간 : ", time.Now())
return
}
}

}

결과

시작 시간: 2022-11-01 22:00:31.372444 +0900 KST m=+0.000148793
context.Background.WithDeadline(2022-11-01 22:02:00 +0900 KST [1m28.627254s])
종료 신호
종료 시간 : 2022-11-01 22:01:59.999401 +0900 KST m=+88.628990210

어느 경우 사용?

  • 어플리케이션 자체의 종료 시그널을 보낼 때 사용한다 => graceful shutdown
  • 고루틴에 종료 신호를 보낼 때 사용한다. ex) 특정 시간안에 처리가 안돼서 고루틴을 중단시키고 싶을 때
  • 100개의 요청을 한번에 실행하려고 할 때 A는 33개 B는 33개 C는 34개 처리할 수 있도록 고루틴 3개를 실행시킨다. 요청이 1분이 지나면 안받는다는 조건을 main context에 걸어놓았다. main context를 하위 고루틴에 뿌려준다. 1분이 지나면 3개의 고루틴이 부모(main) 고루틴이 종료되므로 자식 고루틴 A,B,C 도 죽으면 종료 된다.

참조

https://github.com/YooGenie/go-study/issues/62

​ ​ ​