How to Propagate Cancellation with Context in Go

Use context.Context with cancel functions to signal goroutines to stop, checking ctx.Done() or ctx.Err() to exit tasks immediately.

Propagate cancellation by passing a context.Context to goroutines and checking ctx.Err() or using ctx.Done() to exit early. Use context.WithCancel or context.WithTimeout to create cancellable contexts and pass them to functions that need to stop.

ctx, cancel := context.WithCancel(context.Background())

// Start a goroutine that listens for cancellation
go func() {
    select {
    case <-ctx.Done():
        fmt.Println("Cancelled:", ctx.Err())
        return
    case <-time.After(5 * time.Second):
        fmt.Println("Task completed")
    }
}()

// Cancel the context after 2 seconds
time.Sleep(2 * time.Second)
cancel()

// Wait for goroutine to finish
time.Sleep(1 * time.Second)

For groups of goroutines, use errgroup.WithContext to automatically cancel all tasks when one fails or the context is cancelled:

g, ctx := errgroup.WithContext(context.Background())

for i := 0; i < 5; i++ {
    i := i
    g.Go(func() error {
        select {
        case <-ctx.Done():
            return ctx.Err()
        default:
            // Do work
            return nil
        }
    })
}

if err := g.Wait(); err != nil {
    fmt.Println("Error:", err)
}