대표적인 예가 http.Request
이다.
로그인을 한다고 가정하면 미들웨어에서 인증로직을 처리해야하고
이때 전체 http.Request 객체에 아이디와 비밀번호 구조체를 정의하고 추가로 놓는 것은 비효율적이다.
문맥에 따라서 인증정보가 필요할 때가 있고 더 이상 필요하지 않거나 없애야만 할 때가 있는데 이때 context
를 사용하기 딱 좋다.
Package context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.
- Go document-
👉🏻 한 줄 요약하면 "유효기간이 정해져있고, 실행 중단이 임의로 가능하고, 사용자가 정의할 수 있는 key-value 데이터 담아야할 때" 가 되겠다.
func printInfo(ctx context.Context, waitGroup *sync.WaitGroup) {
tickChannel := time.Tick(time.Second)
for {
select {
case <-tickChannel:
name := ctx.Value("name")
age := ctx.Value("age")
if name != nil {
fmt.Printf("name : %s\n", name.(string))
}
if age != nil {
fmt.Printf("age : %d\n", age.(uint))
}
// context done is called when context receives cancel signals
case <-ctx.Done():
waitGroup.Done()
return
}
}
}
func ContextTest() {
// 한 번 생선된 컨텍스트는 변경될 수 없으므로 값 추가를 원하면
// 새로 할당이 필요하다.
// withTimeout 도 cancel function return 함.
ctx, cancel := context.WithTimeout(context.Background(), time.Second * 5)
ctx = context.WithValue(ctx, "name", "vladimir")
ctx = context.WithValue(ctx, "age", uint(20))
defer cancel()
waitGroup := sync.WaitGroup{}
waitGroup.Add(1)
go printInfo(ctx, &waitGroup)
// As soon as call this function,
// A signal is sent to ctx
waitGroup.Wait()
}
대표 메소드 3세트를 뽑자면
WithCancel
WithValue
WithTimeout
항목 | channel | context |
---|---|---|
Mltiple message or signals | O | O |
Send message again after initialization | O | X |
Data type | 미리 지정 | T (return Interface) |
Life time | 임의 지정 | 임의 지정, 미리 지정 다 가능 |