How to correctly handle context cancellation in Go when using goroutines?
I'm optimizing some code but After trying multiple solutions online, I still can't figure this out... I am facing an issue with handling context cancellation in my Go application, particularly when dealing with multiple goroutines. I am using Go 1.20 and the `context` package to manage cancellation but it seems like some goroutines are still running even after the context is cancelled. Hereβs a simplified version of what I have: ```go package main import ( "context" "fmt" "time" ) func worker(ctx context.Context, id int) { defer fmt.Printf("Worker %d finished\n", id) for { select { case <-ctx.Done(): fmt.Printf("Worker %d received cancellation\n", id) return default: // Simulate work time.Sleep(1 * time.Second) fmt.Printf("Worker %d working...\n", id) } } } func main() { ctx, cancel := context.WithCancel(context.Background()) for i := 1; i <= 3; i++ { go worker(ctx, i) } time.Sleep(3 * time.Second) fmt.Println("Cancelling context...") cancel() time.Sleep(2 * time.Second) } ``` When I run this code, I expect that all workers should stop after the context is cancelled. However, it seems like they continue to run for a while before finishing. The output shows that some workers still log "working..." even after the "Cancelling context..." message appears. I thought that using `ctx.Done()` in the select statement would immediately stop the goroutines, but it appears that the workers are still processing in the default case. Is there a way to ensure that once the context is cancelled, all workers terminate immediately? Am I missing something in the goroutine design or context usage? What am I doing wrong? I'd love to hear your thoughts on this.