How to use contexts in Go
· 2 min read
- example
- request URL in a web app
- connection status e.g. to stop processing when the client disconnects or times out
contextpackagecontext.TODO()creates an empty placeholder contextcontext.Backgroundalso creates an empty context- deciding which to use is about signaling intent to other developers
- use
Backgroundwhen you "intend to start a known context" - it's a good default option if you aren't sure
- each layer of an app can add its own information to the context using
context.WithValue(ctx, k, v)to create a new context containing that new value- this new context will have the original context as the "parent context"
- contexts are immutable
- When to use a value in a context vs explicit param
- depends on what the function is doing with the value
- e.g. if you have a function that explicitly operates on a username, you should pass that in rather than relying on the context
- mostly about signaling developer intent
- Ending a context
- using
Donereturns a channel that can be watched for values. it will never be written to until the context is done so you can check it to know when to stop processing - can only perform one channel operation per
selectbut can put that select in a loop - adding
defaultto the select will keep it from blocking - in the example of a loop that tries to either read from
Doneor from another channel,defaultjust means it starts another loop immediately instead of waiting. This is called a "busy loop". The external behavior is the same though context.WithCancelreturns(new context, cancellation function)- canceling a context does not automatically cancel the parent context
context canceledis a common error in http apps when the client disconnects mid-response
- using
context.WithDeadline- will cancel context automatically
- error will be
context deadline exceeded - there is a convenience wrapper around this called
context.WithTimeout