Kontexte in Go verstehen

Kontexte in Go verstehen

Kontext ist eine der entscheidenden Funktionen in Go, die Parallelität ermöglicht. In Go bezieht sich „Kontext“ auf ein Paket, das Funktionen für anforderungsbezogene Werte und Abbruchsignale über API-Grenzen hinweg bereitstellt.

Das Kontextpaket arbeitet gleichzeitig mit dem Parallelitätsmodell von Go, basierend auf dem Konzept der Goroutinen. Goroutinen sind leichtgewichtige Ausführungsthreads, die Sie effizient erstellen und verwalten können, wodurch es einfach ist, gleichzeitige Programme in Go zu erstellen.

Das Kontextpaket

Das Kontextpaket bietet Funktionen zum Abbrechen lang andauernder Funktionen oder ganzer Aufrufketten. Das Paket hilft auch beim Speichern von anforderungsbezogenen Werten für den Zugriff überall in der Aufrufkette. Diese Funktion ist praktisch, wenn Sie mit APIs oder Microservices arbeiten, bei denen Anforderungen mehrere Funktionsaufrufe umfassen können und Sie sie abbrechen oder ihnen bestimmte Werte zuweisen möchten.

So können Sie das Kontextpaket in Ihre Go-Programme importieren.

import "context"

Kontextfunktionen übernehmen den Kontextstrukturtyp des Kontextpakets. Üblicherweise sollten Sie ctx als Namen der Instanzvariablen verwenden.

func operations(ctx context.Context) {
}

Funktionen können den Strukturtyp Context für andere Funktionen und Operationen zurückgeben.

func operations(ctx context.Context) context.Context {
}

Mit der TODO -Funktion des Kontextpakets können Sie einen neuen Kontext erstellen. Die TODO-Funktion erstellt einen neuen Kontext mit dem Wert von context.Done() , einem Kanal, der bei Kontextabbruch geschlossen wird. Sie sollten es als Platzhalter verwenden, wenn Sie einen Kontext benötigen, aber keine übergeordneten Kontexte geeignet sind.

import "context"

func main() {
    ctx: = context.TODO()
}

Alternativ erstellt die Background -Funktion einen neuen Kontext ohne Wert und einen leeren Done-Kanal.

ctx: = context.Background()

Sie sollten die Background-Funktion als Stamm einer Kontextstruktur verwenden.

Kontext mit Werten

Das Kontextpaket stellt Funktionalität zum Weitergeben von Werten und Abbruchsignalen bereit. Sie können die Werte für Informationen von anfragebezogenen Daten bis hin zu Kündigungssignalen und Fristen verwenden.

Das Kontextpaket ermöglicht auch die Erstellung von untergeordnetem Kontext, der von übergeordneten Kontexten geerbt wird, was eine effiziente Handhabung von Werten und Abbruchsignalen in einem Programm ermöglicht, da Sie den Kontext durch mehrere Funktionen leiten können.

Hier ist ein Beispiel für die Übergabe von Kontext durch Funktionen mit dem Kontextpaket.

import (
    "context"
)

func valuableContext(ctx context.Context) context.Context {
    return context.WithValue(ctx, "pass-key", "hfouneqcelkwfu")
}


func receiveContextData(ctx context.Context) any {
    passKey: = ctx.Value("pass-key")
    return passKey
}

Die valueContext- Funktion übernimmt eine Kontextinstanz und gibt eine Kontextinstanz für die folgende Funktion zurück. Die Kontextinstanz ist ein Wert, der mit der WithValue- Methode erstellt wurde. Die WithValue-Methode nimmt die Kontextinstanz aus der Funktion und ein Schlüssel-Wert-Paar.

Um die Daten aus dem Kontext abzurufen, müssen Sie mit der Funktion TODO oder Background einen neuen Kontext erstellen und den Kontext an die Funktion (in diesem Fall valueContext) übergeben und den Kontext mit der Funktion ReceiveContextData empfangen .

func main() {
    ctx: = context.Background()
    ctx = valuableContext(ctx)
    fmt.Println(receiveContextData(ctx))

}

Die ctx-Variable ist die Kontextinstanz aus der Background-Funktion. Die Funktion „valuableContext“ übernimmt die Variable „ctx“ und gibt den Kontext mit einem Wert zurück, den die Funktion „receiveContextData“ übernimmt und den Wert aus dem Schlüssel-Wert-Paar zurückgibt.

Kontext nach Wertcodeergebnis

Kontext-Timeouts und Fristen

Das Kontextpaket bietet Funktionen zum Festlegen von Zeitüberschreitungen und Fristen im Betrieb. Das Festlegen von Zeitüberschreitungen und Fristen ist hilfreich für Vorgänge, die aufholen müssen.

Timeouts sind die Dauer einer Operation. Sie können ein Zeitlimit für einen Vorgang auf 4 Sekunden festlegen; Danach bricht der Kontext die Anfrage ab.

Andererseits definiert eine Frist den absoluten Punkt, an dem ein Vorgang abgebrochen werden sollte.

Sie können die WithTimeout- Methode verwenden, um ein Kontexttimeout festzulegen. So können Sie ein 2-Sekunden-Timeout festlegen.

func main() {
    ctx, cancel: = context.WithTimeout(context.Background(), 2 * time.Second)
    defer cancel()

    // some operation
}

Die Hauptfunktion erstellt einen Kontext mit einem Timeout von zwei Sekunden. Die WithTimeout-Funktion gibt eine Abbruchfunktion zurück, die Sie für den Abbruch beim Beenden der Hauptfunktion zurückstellen können.

Sie können Fristen mit der Methode WithDeadline deklarieren . Die WithDeadline-Methode übernimmt eine Kontextinstanz und eine Deadline-Zeit.

func doSomething(ctx context.Context) {
    deadlineTime: = time.Now().Add(1500 * time.Millisecond)
    ctx, ctxCancel: = context.WithDeadline(ctx, deadlineTime)
    defer ctxCancel()

    // some operation


    ctxCancel()
}

Die doSomething- Funktion nimmt einen Kontext auf, und die DeadTime- Variable ist die Zeit vor dem Kontext -Termin. Die ctx- Variable ist der Kontext mit einer Frist.

Die Variable ctxCancel bricht den Kontext ab, wenn der Kontext seine Frist überschreitet.

Best Practices für die Verwendung von Kontexten in Go

Vermeiden Sie die Verwendung von Kontexten als globale Variablen. Die Verwendung von Kontexten als globale Variablen kann zu unerwartetem Codeverhalten und schwer nachzuvollziehenden Fehlern führen, und verwenden Sie den Kontext sparsam, um die Codekomplexität zu reduzieren.

Verwenden Sie schließlich Kontexte als Signale, nicht als Garantien. Das Abbrechen eines Kontexts garantiert nicht, dass alle Goroutinen aufhören zu laufen; es ist lediglich ein Signal, und Goroutinen sind kontextunabhängig.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert