Skip to content

Instantly share code, notes, and snippets.

@BenSlabbert
Created June 3, 2020 12:13
Show Gist options
  • Save BenSlabbert/422d71b1bbe4eeb636d3d75ed86dcc84 to your computer and use it in GitHub Desktop.
Save BenSlabbert/422d71b1bbe4eeb636d3d75ed86dcc84 to your computer and use it in GitHub Desktop.
golang nesting conexts with cancel
package main
import (
"context"
"fmt"
"time"
)
func main() {
rollUp()
skipLowest()
closeRoot()
}
func closeRoot() {
root, cancel_root := context.WithCancel(context.Background())
child_1, _ := context.WithCancel(root)
child_2, _ := context.WithCancel(child_1)
go func() {
<-time.After(250 * time.Millisecond)
cancel_root()
}()
select {
case <-child_2.Done():
fmt.Println("child_2 done!")
}
select {
case <-child_1.Done():
fmt.Println("child_1 done!")
fmt.Println("stopping root")
}
select {
case <-root.Done():
fmt.Println("root done!")
}
}
func skipLowest() {
root, cancel_root := context.WithCancel(context.Background())
child_1, cancel_1 := context.WithCancel(root)
child_2, _ := context.WithCancel(child_1)
go func() {
<-time.After(250 * time.Millisecond)
cancel_1()
}()
select {
case <-child_2.Done():
fmt.Println("child_2 done!")
}
select {
case <-child_1.Done():
fmt.Println("child_1 done!")
fmt.Println("stopping root")
cancel_root()
}
select {
case <-root.Done():
fmt.Println("root done!")
}
}
func rollUp() {
root, cancel_root := context.WithCancel(context.Background())
child_1, cancel_1 := context.WithCancel(root)
child_2, cancel_2 := context.WithCancel(child_1)
go func() {
<-time.After(250 * time.Millisecond)
cancel_2()
}()
select {
case <-child_2.Done():
fmt.Println("child_2 done!")
fmt.Println("stopping child_1")
cancel_1()
}
select {
case <-child_1.Done():
fmt.Println("child_1 done!")
fmt.Println("stopping root")
cancel_root()
}
select {
case <-root.Done():
fmt.Println("root done!")
}
}
@BenSlabbert
Copy link
Author

To demonstrate creating child contexts from a root context and how cancelling the various contexts impact one another.

This works because we do not get a runtime panic: all goroutines are asleep - deadlock!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment