Golang Context
Golang Context Sample
Golang Context
WithCancel
package main
import (
"context"
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
// 웨이팅 그룹은 메인에서 서부 루틴이 졸요하는 시점까지 기다림.
wg.Add(1)
// context 생성.
ctx, cancel := context.WithCancel(context.Background())
// 무한 루프 시작...
go PrintTick(ctx)
// 5초 후에 cancel 실행.
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())
// waitGroup을 이곳에서 종료...
wg.Done()
return
case <-tick:
fmt.Println("tick")
}
}
}
WithDeadline
package main
import (
"context"
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
wg.Add(1)
// 현제시간에 5초을 추가해서 데드라인으로 설정.
d := time.Now().Add(5 * time.Second)
ctx, cancel := context.WithDeadline(context.Background(), d)
go PrintTick(ctx)
time.Sleep(time.Second * 5)
cancel()
wg.Wait()
}
func PrintTick(ctx context.Context) {
tick := time.Tick(time.Second)
for {
select {
case <-ctx.Done():
fmt.Println("Done:", ctx.Err())
// waitGroup을 이곳에서 종료...
wg.Done()
return
case <-tick:
fmt.Println("tick")
}
}
}
WithTimeout
package main
import (
"context"
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
wg.Add(1)
// 3초후 종료...
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
go PrintTick(ctx)
// 5초후 cancel이 예정되어 있어도 영향을 주지 않음.
time.Sleep(time.Second * 5)
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")
}
}
}
WithValue
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)
fmt.Println("Square:", n*n)
}
wg.Done()
}
Wrapping
package main
import (
"context"
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
wg.Add(1)
// multi value을 전달하기 위해서는 wrapping이 사용 된다.
ctx, cancel := context.WithCancel(context.Background())
ctx = context.WithValue(ctx, "s", 2)
ctx = context.WithValue(ctx, "t", 3)
go PrintTick(ctx)
// 5초후 종료...
time.Sleep(5 * time.Second)
cancel()
wg.Wait()
}
func PrintTick(ctx context.Context) {
tick := time.Tick(time.Second)
// 어떤 값을 받을지는 선택하면 된다. "s", "t"...
// any -> int 변경하는 부분 참조...
if v := ctx.Value("s"); v != nil {
s := v.(int)
tick = time.Tick(time.Duration(s) * time.Second)
}
for {
select {
case <-ctx.Done():
fmt.Println("Done:", ctx.Err())
wg.Done()
return
case <-tick:
fmt.Println("tick")
}
}
}
댓글남기기