Het package context is de standaard voor het beheren van de levensduur (annulering, time-out) en het doorgeven van metadata tussen delen van de code, vooral bij het werken met goroutines en externe oproepen (HTTP, DB).
Creëren:
Het is belangrijk om de context te beëindigen voor de juiste vrijgave van middelen. Voorbeeld:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() // daarna wordt ctx gebruikt in goroutine/HTTP-aanroep
Typisch patroon — geef context als eerste argument aan functies, voorbeeld:
func process(ctx context.Context) error { ... }
Wanneer kun je context.TODO() en context.Background() doorgeven in plaats van de echte context, en wat is het verschil tussen hen?
Veel mensen gebruiken context.Background() als placeholder. Maar:
context.Background() — wortel van de boom, gebruik alleen in main() en tests, bij de initialisatie van de "contextboom" zelf.context.TODO() is nodig als het nog niet duidelijk is welke context nodig is — voor tijdelijke "oplossingen" tijdens refactoring. In productiecoded is TODO onaanvaardbaar: je moet precies weten wat en waarover wordt doorgegeven.Verhaal
In de microservice vergaten ze cancel() aan te roepen na het aanmaken van context.WithTimeout() — aanvragen kwamen vast te zitten, beëindigde goroutines lieten "hangende" timers achter in de runtime, wat leidde tot geheugenlekken.
Verhaal
Door context.Background() door te geven in plaats van de context die uit de aanvraag kwam in handlers, werd de hele keten van annulering en trace-id verloren, waardoor time-outbeperkingen niet werkten en annuleringen van aanvragen niet plaatsvonden.
Verhaal
Via context.WithValue() gaven ontwikkelaars gegevens door, maar de sleutels waren strings. Als gevolg hiervan, door mogelijke sleutelconflicten uit verschillende pakketten, ontstonden onverwachte fouten ("sleutel is al bezet"). Goede praktijk: gebruik unieke types voor sleutels.