ref by
Context
- 일반적인 Programing Language에서, context는 코드 또는 변수의 실행 환경이나 상황을 나타낸다.
- 변수, 함수 객체 등의 정보를 담고 있다.
- 작업 가능한 시간, 작업 취소 등 작업의 흐름을 제어하는데 사용
- 어디서든, 어떤 것이든 담을 수 있는 key-value 맵이나 접근 가능한 thread-loca storage에서 사용할 수 있다
- Golang에서 context는 고루틴간 작업을 조율하고 취소, 값, 타임아웃 등을 설정하는 기능을 제공하는 도구이다.
- go routine 생명주기를 관리한다
- 특정 비즈니스 로직에 불필요한 connection을 줄여준다.
- 주로 동시성 작업을 조정/취소하며, 요청 범위 값을 전달하는데 사용된다.
Context 초기화
- 주로 다음 두가지를 통해 Context를 생성한다
Context.Background()
- 최상단에서 사용되는 Context
- 서버를 시작하는데 사용이 되는 Context 같은 경우에 사용된다.
Context.Todo()
- 어떤 context를 사용해야 할지 모를때 사용된다.
- context를 생성하면, 아래 메서드들을 사용할 수 있다.
func WithValue(parent Context, key, val interface{}) Context
- channel과 같은 서브 고루틴에 데이터를 전달할 수 있다.
context.Value(key)
로 value 값을 가져올 수 있다.- 이때, 반환값이 interface 타입이기 때문에 가져온 값에 대해 type assertion을 해준다.
package main
import (
"context"
"fmt"
"sync"
)
var wg sync.WaitGroup
func main() {
wg.Add(1)
ctx := context.WithValue(context.Background(), "v", 3)
go square(ctx)
wg.Wait()
}
func square(ctx context.Context) {
if v := ctx.Value("v"); v != nil {
n := v.(int) // -> type assertion
fmt.Println("Square:", n*n)
}
wg.Done()
}
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
- cancel()을 통해 컨택스트를 종료시킬 수 있다. → 고루틴의 생명주기를 제어할 수 있다.
- 대상 컨텍스트와, 컨택스트에 종료 신호를 보낼 수 있는 함수(cancel)를 리턴한다.
- cancel을 호출하면,
ctx.Done()
으로 취소 여부를 확인할 수 있다. Done()
: 종료 신호를 전달받을 수 있는 채널을 반환한다. → 종료 신호를 받은 것을Done()
메서드를 통해 알 수 있음
ctx.withCancel()
로 리턴되는 context는 인자 context의 자식이다.- 취소 함수가 호출되면, 부모 context들에게 처리 중지 시점을 알린다.
package main
import (
"context"
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
wg.Add(1)
ctx, cancel := context.WithCancel(context.Background())
go PrintTick(ctx)
time.Sleep(5 * time.Second)
cancel()
wg.Wait()
}
func PrintTick(ctx context.Context) {
tick := time.Tick(time.Second)
for {
select {
case <-ctx.Done():
fmt.Println("Done:", ctx.Err())
wg.Done()
return
case <-tick:
fmt.Println("tick")
}
}
}
tick
tick
tick
tick
tick
Done: context canceled
context.withDeadline
, context.withTimeout
withcancel()
때와 비슷하다. 일정 시간이 되면 컨텍스트에 자동으로 취소 신호가 전달된다.
deadline
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
- 지정 시간이 되면 컨택스트에 취소 신호가 전달된다.
timeout
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
- duration 시간 후에 취소 시간이 전달된다.
- 다른점은
Deadline
는 언제까지 유지할 것인지고,Timeout
은 얼마동안 유지할지이다.
Share article