Go context timeout 전까지 반복하기
package main
import (
"context"
"log"
"os"
"time"
)
func main() {
logger := log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile)
duration, _ := time.ParseDuration("1s")
ticker := time.NewTicker(duration)
defer ticker.Stop()
for range ticker.C {
ctx, cancel := context.WithTimeout(context.Background(), duration)
go func(ctx context.Context) {
ints := make([]int, 10)
logger.Printf("%#v", ints)
INTS:
for i := range ints {
select {
case <-ctx.Done():
logger.Printf("timeout. err:%#v", ctx.Err())
break INTS
default:
time.Sleep(110 * time.Millisecond)
logger.Printf("I am a long time job:%d", i)
}
}
}(ctx)
defer cancel()
}
}
출력
2019/08/29 16:14:45 main.go:20: []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
2019/08/29 16:14:45 main.go:29: I am a long time job:0
2019/08/29 16:14:45 main.go:29: I am a long time job:1
2019/08/29 16:14:45 main.go:29: I am a long time job:2
2019/08/29 16:14:45 main.go:29: I am a long time job:3
2019/08/29 16:14:45 main.go:29: I am a long time job:4
2019/08/29 16:14:45 main.go:29: I am a long time job:5
2019/08/29 16:14:45 main.go:29: I am a long time job:6
2019/08/29 16:14:46 main.go:29: I am a long time job:7
2019/08/29 16:14:46 main.go:20: []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
2019/08/29 16:14:46 main.go:29: I am a long time job:8
2019/08/29 16:14:46 main.go:25: timeout. err:context.deadlineExceededError{}
2019/08/29 16:14:46 main.go:29: I am a long time job:0
2019/08/29 16:14:46 main.go:29: I am a long time job:1
...
마음에 들지 않는다...
1. 마지막 1회 실행이 timeout 뒤로 넘어감
주의
1. cancel()을 defer하지 않으면 for select에서 default로 넘어가지 못하고 바로 ctx.Done()을 수신