Comment sont structurés les contextes dans le langage Go?
sobes.tech IA
Réponse de l'IA
Le contexte (context.Context) en Go est utilisé pour transmettre des informations sur les délais, les annulations et d'autres données entre les limites d'API. Il représente un arbre : chaque contexte est un enfant d'un autre, sauf le racine (context.Background() ou context.TODO()).
Les méthodes principales de l'interface context.Context :
Deadline() (deadline time.Time, ok bool): Renvoie la date limite du contexte.Done() <-chan struct{}: Renvoie un canal qui se ferme lors de l'annulation du contexte.Err() error: Renvoie l'erreur qui a causé l'annulation du contexte.Value(key any) any: Renvoie la valeur associée à la clé dans le contexte.
Ils sont créés avec des fonctions du paquet context :
context.Background(): Le contexte racine vide, utilisé comme base pour le processus principal.context.TODO(): Utilisé comme marqueur de position lorsque l'on ne sait pas quel contexte utiliser.context.WithCancel(parent Context): Crée un contexte enfant et une fonction d'annulation.context.WithDeadline(parent Context, d time.Time): Crée un contexte enfant avec une date limite.context.WithTimeout(parent Context, timeout time.Duration): Crée un contexte enfant avec un délai d'expiration.context.WithValue(parent Context, key, val any): Crée un contexte enfant avec une valeur.
Principales implémentations de Context :
emptyCtx: Basique, non annulable et sans valeurs. UtiliseBackgroundetTODO.cancelCtx: Supporte l'annulation. Se compose d'un contexte de base et d'un canal d'annulation.timerCtx: Supporte la date limite/le délai d'expiration. ContientcancelCtxet un temporisateur.valueCtx: Supporte la transmission de valeurs. Contient un contexte de base et une paire clé-valeur.
Lorsqu'un contexte parent est annulé, tous ses enfants le sont automatiquement. Cela permet de propager des signaux d'annulation ou des délais dans la chaîne d'appels.
Exemple d'utilisation de context.WithCancel :
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Créer le contexte racine et la fonction d'annulation
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // Garantit l'annulation à la sortie de main
go func() {
select {
case <-ctx.Done(): // Attendre l'annulation du contexte
fmt.Println("Tâche annulée :", ctx.Err())
return
case <-time.After(5 * time.Second): // Ou terminer après 5 secondes
fmt.Println("Tâche terminée")
}
}()
// Annuler le contexte depuis un autre endroit
time.Sleep(1 * time.Second)
fmt.Println("Annulation du contexte...")
cancel()
// Donner du temps au goroutine pour traiter l'annulation
time.Sleep(100 * time.Millisecond)
}
Exemple d'utilisation de context.WithValue :
package main
import (
"context"
"fmt"
)
type userIDKey string
func processRequest(ctx context.Context) {
if userID, ok := ctx.Value(userIDKey("UserID")).(string); ok {
fmt.Println("Traitement de la requête pour l'ID utilisateur :", userID)
} else {
fmt.Println("ID utilisateur non trouvé dans le contexte")
}
}
func main() {
ctx := context.WithValue(context.Background(), userIDKey("UserID"), "12345")
processRequest(ctx)
}
Les contextes sont sûrs pour la concurrence et immuables, ce qui est important pour le code concurrent. Ils ne sont pas destinés à transmettre des paramètres bruts de fonctions, mais plutôt des métadonnées influant sur l'exécution du processus.