Problems

  • Cancel goroutines started by another goroutine. Like Akka actors.
  • To finish task in specified duration or exit gracefully.
  • To finish a task before a specified deadline (timestamp).

Introduction

uses : - passing data downstream from the origin of parent context - cancel an operation in progress. giving features like actors in erlang

Prevent the system from doing unnecessary work hence preserving resources.

Context Tree

https://golangbyexample.com/using-context-in-golang-complete-guide/

Mechanics

  • Emitting the cancellation event. From the caller of the operation
  • Listening the cancellation. From the callee of the operation.

Example Listening

func main() {
	_ = http.ListenAndServe(":8000", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		_, _ = fmt.Fprint(os.Stdout, "processing request\n")
		select {
		case <-time.After(2 * time.Second):
			_, _ = w.Write([]byte("request processed"))
		case <-ctx.Done():
			_, _ = fmt.Fprint(os.Stderr, "request cancelled\n")
		}
	}))
}

Example cancellation

  1. cancelling based on error condition
ctx , cancel := context.WithCancel()

// do something
// catch error

err != nil {
    cancel() // this will abort any downstream operations
}
  1. timebased cancellations
// will cancel context after 3 seconds.
// In the meantime if there are any errors, cancel can be called as well
ctx , cancel := context.WithTimeout(ctx, 3 * time.Second)


// context will be cancelled at specific timestamp
ctx , cancel := context.WithDeadline(ctx, time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC))

Gotchas

  • Context can be cancelled only once.
  • Same context should be passed to all the functions and goroutines from parent. Passing an already cancellable ctx may cause unwanted results.

https://stackoverflow.com/questions/53009084/parent-child-context-cancelling-order-in-go