Sobes.tech
Junior

Was ist der Kontext in Go?

sobes.tech KI

Antwort von AI

Der Kontext (context.Context) in Go ist ein Objekt, das eine Frist, ein Abbruchsignal und spezifische Daten für die Anfrage trägt. Er wird verwendet, um den Lebenszyklus von Goroutines zu verwalten und Informationen zwischen ihnen während der Ausführung einer Anfrage/Operation zu übertragen.

Hauptmerkmale:

  • Gleichzeitig sicher: Kann sicher zwischen Goroutines übertragen werden.
  • Unveränderlich: Einmal erstellt, kann ein Context nicht geändert werden. Abgeleitete Kontexte werden auf Basis des Elternteils erstellt.
  • Hierarchisch: Kontexte bilden einen Baum mit Wurzel (context.Background() oder context.TODO()). Das Abbrechen des Elternkontexts führt zum Abbruch aller Kindkontexte.

Hauptfunktionen des Pakets context:

  • context.Background() : Leerer Kontext, der in der main-Funktion, bei hochrangigen Anfragen oder beim Testen verwendet wird. Wird niemals abgebrochen.
  • context.TODO() : Ebenfalls ein leerer Kontext. Wird als Platzhalter verwendet, wenn nicht bekannt ist, welcher Kontext verwendet werden soll, oder wenn die Funktionalität des Kontexts noch nicht implementiert ist.
  • context.WithCancel(parent Context) : Gibt einen neuen Kindkontext und eine Abbruchfunktion zurück. Das Aufrufen der Abbruchfunktion bricht diesen Kontext und alle seine Kindkontexte ab.
  • context.WithDeadline(parent Context, deadline time.Time) : Gibt einen Kindkontext zurück, der automatisch abgebrochen wird, wenn die angegebene Zeit erreicht ist. Gibt auch eine Abbruchfunktion für manuelles Abbrechen zurück.
  • context.WithTimeout(parent Context, timeout time.Duration) : Das gleiche wie WithDeadline, aber mit Angabe einer Dauer.
  • context.WithValue(parent Context, key, val interface{}) : Gibt einen Kindkontext mit einem Wert für einen Schlüssel zurück.

Anwendungen:

  • Operationen abbrechen: Zum Beispiel, Timeout bei einer HTTP-Anfrage oder Unterbrechung einer längeren Operation.
  • Daten übertragen: Zum Beispiel, Anforderungs-ID für das Logging, Authentifizierungsinformationen.

Beispiel für die Verwendung von context.WithTimeout:

package main

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

func longRunningOperation(ctx context.Context, resultChan chan string) {
	select {
	case <-time.After(3 * time.Second):
		// Operation erfolgreich abgeschlossen
		resultChan <- "Operation abgeschlossen"
	case <-ctx.Done():
		// Kontext wurde abgebrochen
		err := ctx.Err() // Grund für den Abbruch erhalten
		resultChan <- fmt.Sprintf("Operation abgebrochen: %v", err)
	}
}

func main() {
	// Erstellen eines Kontexts mit 2 Sekunden Timeout
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel() // Sicherstellen, dass die Abbruchfunktion aufgerufen wird

	resultChan := make(chan string, 1)

	go longRunningOperation(ctx, resultChan)

	// Warten auf Ergebnis oder Abbruch
	select {
	case res := <-resultChan:
		fmt.Println(res)
	case <-ctx.Done():
		fmt.Printf("Hauptkontext beendet: %v\n", ctx.Err())
	}

	// Kurzes Warten, damit die Goroutine bei Abbruch beendet werden kann
	time.Sleep(1 * time.Second)
}

In diesem Beispiel überprüft longRunningOperation, ob der Kontext abgebrochen wurde. Wenn der Timeout des Hauptkontexts (2 Sekunden) vor Abschluss der Operation (3 Sekunden) eintritt, erhält die Goroutine das Abbruchs-Signal über ctx.Done() und beendet sich.