CodexBloom - Programming Q&A Platform

Goroutine Leak When Using WaitGroup and HTTP Handler with Context in Go

👀 Views: 163 đŸ’Ŧ Answers: 1 📅 Created: 2025-06-07
go concurrency http context waitgroup Go

Quick question that's been bugging me - I'm having a hard time understanding I'm working with a goroutine leak in my Go application when using `sync.WaitGroup` in conjunction with HTTP handlers that accept context. The scenario arises when the HTTP requests are canceled or timeout, but the goroutine that processes data continues running, leading to resource exhaustion. Here's a simplified version of my code: ```go package main import ( "context" "fmt" "net/http" "sync" "time" ) var wg sync.WaitGroup func processTask(ctx context.Context) { defer wg.Done() select { case <-time.After(10 * time.Second): // Simulate work fmt.Println("Task completed") case <-ctx.Done(): fmt.Println("Task canceled") } } func handler(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 5 * time.Second) defer cancel() wg.Add(1) go processTask(ctx) wg.Wait() fmt.Fprintln(w, "Request processed") } func main() { http.HandleFunc("/process", handler) http.ListenAndServe(":8080", nil) } ``` When I call the `/process` endpoint and it takes longer than the context timeout (5 seconds), I see the output `Task completed` even though the request was canceled. The goroutine continues to run, which shouldn't happen. I've tried using `context.WithCancel`, but it doesn't seem to solve the question. Is there a proper way to ensure that the goroutine stops when the context is canceled? Could this be due to the way I'm handling the `WaitGroup`? Any advice on best practices for managing goroutines with cancellation in Go would be appreciated. Any help would be greatly appreciated! Thanks for taking the time to read this!