Sobes.tech
Junior

Wat is de context in Go?

sobes.tech AI

Antwoord van AI

De context (context.Context) in Go is een object dat een deadline, een cancelatiesignaal en gegevens die specifiek zijn voor de aanvraag, meedraagt. Het wordt gebruikt om de levenscyclus van goroutines te beheren en informatie tussen hen over te dragen tijdens de uitvoering van een aanvraag/operatie.

Belangrijkste kenmerken:

  • Veilig voor gelijktijdigheid: Kan veilig tussen goroutines worden overgedragen.
  • Onveranderlijk: Eenmaal gemaakt, kan een Context niet worden gewijzigd. Afgeleide contexten worden op basis van de ouder gemaakt.
  • Hiërarchisch: Contexten vormen een boom met een wortel (context.Background() of context.TODO()). Het annuleren van de oudercontext leidt tot het annuleren van alle kindcontexten.

Belangrijkste functies van het context-pakket:

  • context.Background() : Lege context, wordt meestal gebruikt in de main-functie, bij high-level verzoeken of tijdens testen. Wordt nooit geannuleerd.
  • context.TODO() : Ook een lege context. Wordt gebruikt als placeholder wanneer niet bekend is welke context gebruikt moet worden, of wanneer de functionaliteit van de context nog niet is geïmplementeerd.
  • context.WithCancel(parent Context) : Geeft een nieuwe kindcontext en een cancelfunctie terug. Het aanroepen van deze functie annuleert deze context en alle onderliggende contexten.
  • context.WithDeadline(parent Context, deadline time.Time) : Geeft een kindcontext die automatisch wordt geannuleerd wanneer de opgegeven tijd is bereikt. Geeft ook een cancelfunctie voor handmatige annulering.
  • context.WithTimeout(parent Context, timeout time.Duration) : Hetzelfde als WithDeadline, maar met een duur.
  • context.WithValue(parent Context, key, val interface{}) : Geeft een kindcontext met een waarde gekoppeld aan een sleutel.

Toepassingen:

  • Operaties annuleren: Bijvoorbeeld, een timeout voor een HTTP-verzoek of het onderbreken van een langdurige operatie.
  • Gegevens overdragen: Bijvoorbeeld, aanvraag-ID voor logging, authenticatie-informatie.

Voorbeeld van gebruik van context.WithTimeout:

package main

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

func longRunningOperation(ctx context.Context, resultChan chan string) {
	select {
	case <-time.After(3 * time.Second):
		// Operatie succesvol voltooid
		resultChan <- "Operatie voltooid"
	case <-ctx.Done():
		// Context is geannuleerd
		err := ctx.Err() // Reden van annulering krijgen
		resultChan <- fmt.Sprintf("Operatie geannuleerd: %v", err)
	}
}

func main() {
	// Maak een context met een timeout van 2 seconden
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel() // Zorg dat cancel wordt aangeroepen

	resultChan := make(chan string, 1)

	go longRunningOperation(ctx, resultChan)

	// Wacht op resultaat of annulering
	select {
	case res := <-resultChan:
		fmt.Println(res)
	case <-ctx.Done():
		fmt.Printf("Hoofdcontext beëindigd: %v\n", ctx.Err())
	}

	// Wacht even zodat de goroutine kan afsluiten als deze is geannuleerd
	time.Sleep(1 * time.Second)
}

In dit voorbeeld controleert longRunningOperation of de context is geannuleerd. Als de timeout van de hoofdcontext (2 seconden) eerder verloopt dan de operatie (3 seconden), ontvangt de goroutine het annulatiesignaal via ctx.Done() en stopt.