Servers that use Golang handle each request in a separate
context
is a standard package of Golang that makes it easy to pass request-scoped values, cancelation signals, and deadlines across API boundaries to all the goroutines involved in handling a request.
The core of the context
package is the Context
type, which has the following methods:
Done() <- chan struct
: Returns a channel that is closed when the context is canceled or times out. Done may return nil if the context can never be canceled.Deadline() (deadline time.Time, ok bool)
: Returns the time when the context will be canceled or timed out. Deadline returns ok==false
when no deadline is set.Err() error
: Returns an error that explains why the Done channel was closed. If Done is not closed yet, it returns nil.Value(key interface{}) interface{}
: Returns the value associated with key or nil if none.A common use case for context
is handling HTTP requests. Below is an example of an HTTP server that has a handler example()
.
We demonstrate context by handling request cancellation. By default, each request has an associated context
that is accessible using the request.Context()
method. We use the context’s Done
channel to keep track of any cancellation signal.
Now, you can run the server locally and make a request to localhost:5000/example
. If you cancel the request before it is served, and it’s within the first seconds, the request handler will handle the cancellation gracefully and print the server error.
package mainimport ("fmt""net/http""time")// Handler for /example requestfunc example(w http.ResponseWriter, req *http.Request) {fmt.Println("example handler started")// Accessing the context of the requestcontext := req.Context()select {// Simulating some work by the server// Waits 10 seconds and then responds with "example\n"case <-time.After(10 * time.Second):fmt.Fprintf(w, "example\n")// Handling request cancellationcase <-context.Done():err := context.Err()fmt.Println("server:", err)}fmt.Println("example handler ended")}func main() {http.HandleFunc("/example", example)http.ListenAndServe(":5000", nil)}
The
context
package also provides functions to derive newContext
values from existing ones to form a tree. Read more about derived contexts in the official docs.
Free Resources