Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

golang
context
concurrency

Golang context

Educative Answers Team

Servers that use Golang handle each request in a separate goroutinea lightweight thread of execution in Go. These requests sometimes spawn additional goroutines to handle the request. These new goroutines need access to request-specific values like the identity of the end-user or the request’s deadline.

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.

Syntax

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.

Example

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 1010 seconds, the request handler will handle the cancellation gracefully and print the server error.

package main
import (
    "fmt"
    "net/http"
    "time"
)

// Handler for /example request
func example(w http.ResponseWriter, req *http.Request) {

    fmt.Println("example handler started")

    // Accessing the context of the request
    context := 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 cancellation
    case <-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 new Context values from existing ones to form a tree. Read more about derived contexts in the official docs.

RELATED TAGS

golang
context
concurrency
Copyright ©2022 Educative, Inc. All rights reserved
RELATED COURSES

View all Courses

Keep Exploring