프로그래밍/golang
ultimate go-(12) context사용
by 나도한강뷰
2023. 1. 31.
context
- context패키지를 이용해보자
- cancellation과 deadline을 지원한다.
package main
import (
"context"
"fmt"
)
type user struct { // context내에 값을 저장하기 위해 만든 구조체
name string
}
type userKey int // user값에 대한 키 타입
func main()
u := user { //user값 생성
name: "Hoanh",
}
const uk userKey = 0 //key값 0으로 생성
ctx := context.WithValue(context.Background(), uk, &u) // value를 넣기위한 함수 withValue, 키값과 키값으로 찾을 값의 주소값을 저장한다.
// context는 파이프라인을 위해 고안된 형태이므로 그전값을 받는게 필요하다
// 그게 backgroud이다.
if u, ok := ctx.Value(uk).(*user); ok { // uk를 쓰고 타입단언을 통해서 값을 받을 수 있다.
fmt.Println("User", u.name)
}
if _, ok := ctx.Value(0).(*user); !ok { //값은 0이지만, userKey type이 아니기때문에 값을 받을 수 없다.
//그렇기때문에 사용자 정의 키값을 사용하는게 중요하다.
fmt.Println("User Not Found")
}
User Hoanh
User Not Found
with cancel
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
time.Sleep(50 * time.Millisecond)
cancel()
}()
select {
case <-time.After(100 * time.Millisecond):
fmt.Println("moving on")
case <-ctx.Done():
fmt.Println("work complete")
}
}
work complete
with deadline
package main
import (
"context"
"fmt"
"time"
)
type data struct {
UserID string
}
func main() {
deadline := time.Now().Add(150 * time.Millisecond) //deadline 설정
ctx, cancel := context.WithDeadline(context.Background(), deadline) //deadline입력
//비슷한 함수로 withTimeOut이 있다.
defer cancel()
ch := make(chan data, 1)
go func() {
time.Sleep(200 * time.Millisecond)
ch <- data{"123"} //작업이 끝났음을 알린다.
}()
select {
case d := <-ch: //
fmt.Println("work complete", d)
case <-ctx.Done(): //timeout을 감지한다.
fmt.Println("work cancelled")
}
}
work cancelled