Created
June 3, 2020 12:13
-
-
Save BenSlabbert/422d71b1bbe4eeb636d3d75ed86dcc84 to your computer and use it in GitHub Desktop.
golang nesting conexts with cancel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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!