괴발개발 성장기

Study/Go 언어

[Golang] context.WithTimeout과 context.WithDeadline

지니유 2022. 11. 3. 07:16
반응형

 

 

 

 

  • 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

 

context.WithTimeout, context.WithDeadline 공부하기 · Issue #62 · YooGenie/go-study

 

github.com

 

반응형