Sobes.tech
Junior

Qu'est-ce que le contexte en Go?

sobes.tech IA

Réponse de l'IA

Le contexte (context.Context) en Go est un objet qui porte une date limite, un signal d'annulation et des données spécifiques à la requête. Il est utilisé pour gérer le cycle de vie des goroutines et pour transmettre des informations entre elles lors de l'exécution d'une requête/opération.

Caractéristiques principales :

  • Sûr pour la concurrence : Peut être transféré en toute sécurité entre goroutines.
  • Immutable : Une fois créé, un Context ne peut pas être modifié. Les contextes dérivés sont créés à partir du parent.
  • Hiérarchique : Les contextes forment un arbre avec une racine (context.Background() ou context.TODO()). L'annulation du contexte parent entraîne l'annulation de tous ses enfants.

Fonctions principales du paquet context :

  • context.Background() : Contexte vide, généralement utilisé dans la fonction main, dans des requêtes de haut niveau ou lors de tests. Ne peut jamais être annulé.
  • context.TODO() : Également un contexte vide. Utilisé comme placeholder lorsque l'on ne sait pas quel contexte utiliser, ou si la fonctionnalité du contexte n'est pas encore implémentée.
  • context.WithCancel(parent Context) : Retourne un nouveau contexte enfant et une fonction d'annulation. Appeler cette fonction annule ce contexte et tous ses contextes enfants.
  • context.WithDeadline(parent Context, deadline time.Time) : Retourne un contexte enfant qui s'annule automatiquement lorsque l'heure spécifiée est atteinte. Retourne également une fonction d'annulation pour une annulation manuelle.
  • context.WithTimeout(parent Context, timeout time.Duration) : Même chose que WithDeadline, mais avec une durée.
  • context.WithValue(parent Context, key, val interface{}) : Retourne un contexte enfant avec une valeur associée à une clé.

Applications :

  • Annulation d'opérations : Par exemple, un timeout pour une requête HTTP ou l'interruption d'une opération longue.
  • Transmission de données : Par exemple, ID de requête pour la journalisation, informations d'authentification.

Exemple d'utilisation de context.WithTimeout :

package main

import (
	"context"
	"fmt"
	"time"
)

func longRunningOperation(ctx context.Context, resultChan chan string) {
	select {
	case <-time.After(3 * time.Second):
		// Opération terminée avec succès
		resultChan <- "Opération terminée"
	case <-ctx.Done():
		// Le contexte a été annulé
		err := ctx.Err() // Obtenir la cause de l'annulation
		resultChan <- fmt.Sprintf("Opération annulée : %v", err)
	}
}

func main() {
	// Créer un contexte avec un timeout de 2 secondes
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel() // Assurer l'appel à cancel

	resultChan := make(chan string, 1)

	go longRunningOperation(ctx, resultChan)

	// Attendre le résultat ou l'annulation
	select {
	case res := <-resultChan:
		fmt.Println(res)
	case <-ctx.Done():
		fmt.Printf("Contexte principal terminé : %v\n", ctx.Err())
	}

	// Attendre un peu pour que la goroutine se termine si elle a été annulée
	time.Sleep(1 * time.Second)
}

Dans cet exemple, longRunningOperation vérifie si le contexte a été annulé. Si le timeout du contexte principal (2 secondes) expire avant la fin de l'opération (3 secondes), la goroutine reçoit le signal d'annulation via ctx.Done() et se termine.