Go by Example

Context

Using context cancellation and deadlines to stop work across a call chain.

context.Context carries cancellation, an optional deadline, and request-scoped values through a call chain. It lets a caller stop work when a request ends or takes too long.

Accept context as the first parameter by convention. A timeout cancels the context automatically; defer the cancel function to release resources early when work finishes:

package main
 
import (
    "context"
    "fmt"
    "time"
)
 
func fetch(ctx context.Context) error {
    select {
    case <-time.After(time.Second):
        return nil
    case <-ctx.Done():
        return ctx.Err()
    }
}
 
func main() {
    ctx, cancel := context.WithTimeout(
        context.Background(), 100*time.Millisecond,
    )
    defer cancel()
    fmt.Println(fetch(ctx)) // context deadline exceeded
}

In production

Pass context as the first parameter by convention and forward it to downstream calls. Do not store request contexts in structs. Give network and database work a deadline, and check ctx.Done() in long-running loops. Reserve context.WithValue for request-scoped metadata, using a private key type.

Enjoyed this? Get more software craft delivered to your inbox.