Context Package Go Idioms
Incoming requests to a server should create a Context
- Create context early in processing task or request.
- Create a top level context
func main(){ ctx := context.Background() } - http.Request value already contains a Context.
func handleFunc(w http.ResponseWritter, req *http.Request){ ctx, cancel = context.WithCancel(req.Context()) }
Outgoing calls to servers should accept a Context
- Higher level calls need to tell lower level calls how long they are willing to wait. ```go // Create a context with a timeout of 100 milliseconds. ctx, cancel := context.WithTimeout(req.Context(), 100*time.Millsecond) defer cancel()
// Bind the new context into the request req = req.WithContext(ctx)
// Do will handle the context level timeout. resp, err := http.DefaultClient.Do(req) ```
http.DefaultClient.Do()method to respect cancellation signal on timer expiry and return with error message.
Pass a Context to function performing I/O
- Any function that is performing I/O should accept a Context value as it's first parameter and respect any timeout or deadline configured by the caller.
- Any API's that takes a Context, the idiom is to have the first parameter accept the Context value.

Any change to a Context value creates a new Context value that is then propagated forward.

When a Context is cancelled, all Contexts derived from it are also cancelled.
- If a parent Context is cancelled, all children derived by that parent Context are cancelled as well.
Use TODO context if you are unsure about which Context to use
- If a function is not responsible for creating top level context.
- We need a temporary yop-level Context until we figured out where the actual Context will come from.
Use context value only for request-scoped data
- Do not use the Context value to pass data into a function which becomes essential for its successful execution.
- A function should be able to execute its logic with an empty Context value.
Summary
- Incoming requests to a server should create a Context.
- Outgoing calls to servers should accept a Context.
- Any function that performing I/O should accept a Context value.
- If a parent Context is cancelled, all children derived from it are also cancelled.
- Use TODO context if you are unsure about which Context to use.
- Use context values only for request-scoped data, not for passing optional parameters to functions.