Middle
Vertel me over de gebruiksgevallen van de context in Go.
sobes.tech AI
Antwoord van AI
De context in Go wordt gebruikt om de levenscyclus van verzoeken te beheren en de uitvoering van goroutines te controleren. De belangrijkste gebruikssituaties:
- Annulering: Maakt het mogelijk om de keten van goroutines die met een specifiek verzoek verband houden, te annuleren. Bijvoorbeeld bij het sluiten van de verbinding of door timeout.
- Timeout: Stelt een uiterste termijn voor de uitvoering in. Als de operatie niet binnen deze termijn wordt voltooid, wordt de context geannuleerd. Dit voorkomt oneindig wachten.
- Overdracht van verzoekspecifieke gegevens: Maakt het mogelijk om gegevens die betrekking hebben op een specifiek verzoek (zoals gebruikers-ID, trace-identifier) door de call-keten te sturen zonder de handtekeningen te wijzigen.
Voorbeelden van gebruik:
-
Annulering door signaal:
package main import ( "context" "fmt" "time" ) func worker(ctx context.Context, id int) { for { select { case <-ctx.Done(): fmt.Printf("Werker %d onderbroken\n", id) return default: fmt.Printf("Werker %d aan het werk...\n", id) time.Sleep(500 * time.Millisecond) } } } func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Zorgt voor annulering go worker(ctx, 1) go worker(ctx, 2) time.Sleep(2 * time.Second) cancel() // Annuleert de context time.Sleep(500 * time.Millisecond) // Geeft tijd voor goroutines om te eindigen } -
Timeout:
package main import ( "context" "fmt" "time" ) func longOperation(ctx context.Context) error { select { case <-time.After(3 * time.Second): // Simulatie van een lange operatie fmt.Println("Operatie succesvol afgerond") return nil case <-ctx.Done(): fmt.Println("Operatie geannuleerd door context:", ctx.Err()) return ctx.Err() } } func main() { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() err := longOperation(ctx) if err != nil { fmt.Println("Fout:", err) } } -
Overdracht van gegevens:
package main import ( "context" "fmt" ) type UserKey string const userIDKey UserKey = "userID" func processRequest(ctx context.Context) { userID := ctx.Value(userIDKey).(int) fmt.Printf("Verwerking van verzoek voor gebruikers-ID: %d\n", userID) // Verdere verwerking van het verzoek met userID } func main() { ctx := context.WithValue(context.Background(), userIDKey, 123) processRequest(ctx) }
Het is belangrijk om context.Background() of context.TODO() te gebruiken als de root-context en deze door te geven in de call-keten. Het is niet aan te raden om de context op te slaan in datastructuren als deze niet direct gerelateerd is aan de levenscyclus van die structuur.