Context About Context Package in Golang

Pre-requisites

Using context | Examples

func operationOne(ctx context.Context) {
n := 1
for {
select {
case <-ctx.Done():
fmt.Println("context canceled for op-1")
return // returning not to leak the goroutine
default:
fmt.Printf("OperationOne: %d\n", n)
time.Sleep(500 * time.Millisecond)
n++
}
}
}

func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
operationOne(ctx)
}
func operationOne(ctx context.Context) {
n := 1
for {
select {
case <-ctx.Done():
fmt.Println("context canceled for op-1")
return // returning not to leak the goroutine
default:
fmt.Printf("OperationOne: %d\n", n)
time.Sleep(500 * time.Millisecond)
n++
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go operationOne(ctx)
time.Sleep(5 * time.Second)
}
func operationOne(ctx context.Context) {
n := 1
for {
select {
case <-ctx.Done():
fmt.Println("context canceled for op-1")
return // returning not to leak the goroutine
default:
fmt.Printf("OperationOne: %d\n", n)
time.Sleep(500 * time.Millisecond)
n++
}
}
}

func operationTwo(ctx context.Context) {
n := 1
for {
select {
case <-ctx.Done():
fmt.Println("context canceled for op-2")
return // returning not to leak the goroutine
default:
fmt.Printf("OperationTwo: %d\n", n)
time.Sleep(250 * time.Millisecond)
n++
}
}
}

func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
d := time.Now().Add(5000 * time.Millisecond)
ctx, cancel = context.WithDeadline(context.Background(), d)
defer cancel()
go operationOne(ctx)

d = time.Now().Add(10000 * time.Millisecond)
ctx, cancel = context.WithDeadline(context.Background(), d)
defer cancel()
go operationTwo(ctx)

time.Sleep(20 * time.Second)
}
func operationOne(ctx context.Context) {
n := 1
for {
select {
case <-ctx.Done():
fmt.Println("context canceled for op-1")
return // returning not to leak the goroutine
default:
fmt.Printf("OperationOne: %d\n", n)
time.Sleep(500 * time.Millisecond)
n++
}
}
}
func operationTwo(ctx context.Context) {
n := 1
for {
select {
case <-ctx.Done():
fmt.Println("context canceled for op-2")
return // returning not to leak the goroutine
default:
fmt.Printf("OperationTwo: %d\n", n)
time.Sleep(250 * time.Millisecond)
n++
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
d := time.Now().Add(5000 * time.Millisecond)
ctx, _ = context.WithDeadline(context.Background(), d)
go operationOne(ctx)
d = time.Now().Add(10000 * time.Millisecond)
ctx, _ = context.WithDeadline(context.Background(), d)
go operationTwo(ctx)
time.Sleep(3 * time.Second)
}
type Key string  func operationOne(ctx context.Context) {
n := 1
for {
select {
case <-ctx.Done():
fmt.Printf("context canceled for %s\n", ctx.Value(Key("op_id")))
return // returning not to leak the goroutine
default:
fmt.Printf("OperationOne: %d : opeartion_id = %s\n", n, ctx.Value(Key("op_id")))
time.Sleep(500 * time.Millisecond)
n++
}
}
}
func operationTwo(ctx context.Context) {
n := 1
for {
select {
case <-ctx.Done():
fmt.Printf("context canceled for %s\n", ctx.Value(Key("op_id")))
return // returning not to leak the goroutine
default:
fmt.Printf("OperationTwo: %d : opeartion_id = %s\n", n, ctx.Value(Key("op_id")))
time.Sleep(250 * time.Millisecond)
n++
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
d := time.Now().Add(5000 * time.Millisecond)
ctx, cancel = context.WithDeadline(context.Background(), d)
defer cancel()
ctx = context.WithValue(ctx, Key("op_id"), "ONE")
go operationOne(ctx)
d = time.Now().Add(10000 * time.Millisecond)
ctx, cancel = context.WithDeadline(context.Background(), d)
defer cancel()
ctx = context.WithValue(ctx, Key("op_id"), "TWO")
go operationTwo(ctx)
time.Sleep(20 * time.Second)
}
type Key string  func operationOneChild(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Printf("context canceled for %s\n", ctx.Value(Key("op_id")))
return // returning not to leak the goroutine
default:
fmt.Println("Child of operation one")
time.Sleep(100 * time.Millisecond)
}
}
} func operationOne(ctx context.Context) {
n := 1
// go operationOneChild(context.WithValue(ctx, Key("op_id"), "CHILD OF ONE"))
go operationOneChild(nil)
for {
select {
case <-ctx.Done():
fmt.Printf("context canceled for %s\n", ctx.Value(Key("op_id")))
return // returning not to leak the goroutine
default:
fmt.Printf("OperationOne: %d : opeartion_id = %s\n", n, ctx.Value(Key("op_id")))
time.Sleep(500 * time.Millisecond)
n++
}
}
}
func operationTwo(ctx context.Context) {
n := 1
for {
select {
case <-ctx.Done():
fmt.Printf("context canceled for %s\n", ctx.Value(Key("op_id")))
return // returning not to leak the goroutine
default:
fmt.Printf("OperationTwo: %d : opeartion_id = %s\n", n, ctx.Value(Key("op_id")))
time.Sleep(250 * time.Millisecond)
n++
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
d := time.Now().Add(5000 * time.Millisecond)
ctx, cancel = context.WithDeadline(context.Background(), d)
defer cancel()
ctx = context.WithValue(ctx, Key("op_id"), "ONE")
go operationOne(ctx)
d = time.Now().Add(10000 * time.Millisecond)
ctx, cancel = context.WithDeadline(context.Background(), d)
defer cancel()
ctx = context.WithValue(ctx, Key("op_id"), "TWO")
go operationTwo(ctx)
time.Sleep(20 * time.Second)
}
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0xffffffff addr=0x0 pc=0xf3966]
goroutine 9 [running]:
main.operationOneChild(0x0, 0x0)
/tmp/sandbox968352470/prog.go:14 +0xa6
created by main.operationOne
/tmp/sandbox968352470/prog.go:28 +0x40
type Key string  func operationOneChild(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Printf("context canceled for %s\n", ctx.Value(Key("op_id")))
return // returning not to leak the goroutine
default:
fmt.Println("Child of operation one")
time.Sleep(100 * time.Millisecond)
}
}
} func operationOne(ctx context.Context) {
n := 1
go operationOneChild(context.WithValue(ctx, Key("op_id"), "CHILD OF ONE"))
// go operationOneChild(nil)
for {
select {
case <-ctx.Done():
fmt.Printf("context canceled for %s\n", ctx.Value(Key("op_id")))
return // returning not to leak the goroutine
default:
fmt.Printf("OperationOne: %d : opeartion_id = %s\n", n, ctx.Value(Key("op_id")))
time.Sleep(500 * time.Millisecond)
n++
}
}
}
func operationTwo(ctx context.Context) {
n := 1
for {
select {
case <-ctx.Done():
fmt.Printf("context canceled for %s\n", ctx.Value(Key("op_id")))
return // returning not to leak the goroutine
default:
fmt.Printf("OperationTwo: %d : opeartion_id = %s\n", n, ctx.Value(Key("op_id")))
time.Sleep(250 * time.Millisecond)
n++
}
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
d := time.Now().Add(5000 * time.Millisecond)
ctx, cancel = context.WithDeadline(context.Background(), d)
defer cancel()
ctx = context.WithValue(ctx, Key("op_id"), "ONE")
go operationOne(ctx)
d = time.Now().Add(10000 * time.Millisecond)
ctx, cancel = context.WithDeadline(context.Background(), d)
defer cancel()
ctx = context.WithValue(ctx, Key("op_id"), "TWO")
go operationTwo(ctx)
time.Sleep(20 * time.Second)
}

Things to keep in mind while using the context

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store