Goroutine-leaks bij afgebroken requests: context-cancellation goed toepassen
2 berichten · 37 weergaven
D
Devin
Lid
OP #124 juli 2026, 14:26
In een Go-service start ik per inkomende request een paar goroutines voor externe calls. Bij een afgebroken request, als de client afhaakt, blijven die soms hangen en na een tijdje zie ik het geheugen oplopen. Ik geef de request-context wel door, maar ergens lek ik toch een goroutine. Hoe zorgen jullie dat elke goroutine netjes stopt bij cancellation, en waarmee spoor je zo'n leak betrouwbaar op? Ik dacht aan pprof, maar weet niet waar ik precies moet kijken.
Angelo
Lid
#218 augustus 2026, 12:22
Context doorgeven is maar het halve werk: je go-routine moet ook echt op ctx.Done() reageren of een context-bewuste call gebruiken. De klassieke lek is een go-routine die zijn resultaat op een ongebufferd kanaal zet terwijl de lezer (de afgehaakte request) al weg is. Die send blokkeert dan voor eeuwig, en de go-routine blijft hangen.
Meestal los je het zo op:
Meestal los je het zo op:
- Maak je resultkanaal gebufferd: make(chan T, n) met n = aantal go-routines. Dan blokkeert een send niet als er geen lezer meer is. (Alternatief: de send in een select met case <-ctx.Done().)
- Zorg dat de externe call de context echt gebruikt: http.NewRequestWithContext(...) plus een timeout per call via context.WithTimeout. Een call die ctx negeert, cancelt niet.
Handig patroon: errgroup.WithContext. De groep-context wordt gecanceld zodra er eentje faalt of de request afhaakt, en Wait() blokkeert tot ze allemaal terug zijn. Samen met context-bewuste calls stopt alles netjes.