Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
package main
import (
"context"
"sync"
"fmt"
"time"
)
func main() {
var wg sync.WaitGroup
ctx, cancel := context.WithCancel(context.Background())
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("(1) Start Process")
LOOP:
for {
select {
case <-ctx.Done():
fmt.Printf("(1) Canceled by ctx: %s\n", ctx.Err())
break LOOP
case <-time.After(5 * time.Second):
fmt.Println("(1) Heavy work done!")
break LOOP
}
}
fmt.Println("(1) Stop Process")
}()
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("(2) Start Process")
// 7秒にしておけば、大元の Context ctx を待たずに新しい Timeout の Context で終了する
localTimeoutCtx, localCancel := context.WithTimeout(ctx, (2 * time.Second))
// 7秒にしておけば、この下の (2)-(1)プロセスも大元の Context ctx のキャンセルで終了する
// localTimeoutCtx, localCancel := context.WithTimeout(ctx, 7 * time.Second)
defer localCancel()
go func() {
fmt.Println("(2)-(1) Start Process")
LOOP2:
for {
select {
case <-ctx.Done():
fmt.Printf("(2)-(1) Canceld by ctx: %v\n", ctx.Err())
break LOOP2
case <-localTimeoutCtx.Done():
fmt.Printf("(2)-(1) Canceld by localTimeoutCtx: %v\n",
localTimeoutCtx.Err())
break LOOP2
case <-time.After(15 * time.Second):
// 15 秒後に発動されることになっているが、その前にタイムアウトがくるはず
fmt.Println("(2)-(1) ...working...")
}
}
fmt.Println("(2)-(1) End Process")
}()
fmt.Println("(2) Waiting 10 secs...")
time.Sleep(10 * time.Second)
fmt.Println("(2) End Process")
}()
fmt.Println("(0) Waiting 3 secs...")
time.Sleep(3 * time.Second)
fmt.Println("(0) Invoke cancel()")
cancel()
wg.Wait()
fmt.Println("(0) Completed")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment