Heim >Backend-Entwicklung >Golang >Wie klone ich einen Go-Kontext, ohne die Weitergabe abzubrechen?

Wie klone ich einen Go-Kontext, ohne die Weitergabe abzubrechen?

Linda Hamilton
Linda HamiltonOriginal
2024-11-08 14:17:02603Durchsuche

How to Clone a Go Context Without Cancel Propagation?

So klonen Sie einen Go-Kontext ohne Abbruch der Weitergabe

In der Programmiersprache Go überträgt ein context.Context Metadaten und Abbruchsignale zwischen Funktionen und Goroutinen. Es kann jedoch wünschenswert sein, eine Kopie eines Kontexts zu erstellen, die dieselben Werte beibehält, aber nicht den Stornierungsstatus des Originals erbt.

Anwendungsfall:

Dieses Szenario entsteht, wenn der Kontext einer HTTP-Anfrage nach der Rückgabe der Antwort an den Client abgebrochen wird, Sie jedoch eine asynchrone Aufgabe in einer separaten Goroutine ausführen müssen, die wahrscheinlich die übergeordnete Aufgabe überdauert Kontext.

Lösung:

1. Erstellen Sie eine benutzerdefinierte Kontextimplementierung:

Vor Go 1.21 bestand ein Ansatz darin, Ihren eigenen Kontext zu erstellen. Kontextimplementierung, die niemals abgebrochen wird:

import (
    "context"
    "time"
)

type noCancel struct {
    ctx context.Context
}

func (c noCancel) Deadline() (time.Time, bool)       { return time.Time{}, false }
func (c noCancel) Done() <-chan struct{}             { return nil }
func (c noCancel) Err() error                        { return nil }
func (c noCancel) Value(key interface{}) interface{} { return c.ctx.Value(key) }

Dann können Sie erstellen ein neuer Kontext mit dieser Implementierung:

ctxWithoutCancel := WithoutCancel(ctx)

2. Verwenden Sie die WithoutCancel-Funktion (Go 1.21):

Ab Go 1.21 enthält das Kontextpaket eine WithoutCancel-Funktion, die diesen Prozess vereinfacht:

ctxWithoutCancel := context.WithoutCancel(ctx)

Diese Funktion gibt einen neuen Kontext zurück, der teilt die gleichen Werte wie der ursprüngliche Kontext, unterliegt jedoch nicht diesem Abbruch.

Beispiel:

func Handler(ctx context.Context) (interface{}, error) {
    result := doStuff(ctx)
    newContext := context.WithoutCancel(ctx)
    go func() {
        doSomethingElse(newContext)
    }()
    return result
}

Auf diese Weise wird doSomethingElse auch dann weiter ausgeführt, wenn der Anforderungskontext abgebrochen wurde.

Das obige ist der detaillierte Inhalt vonWie klone ich einen Go-Kontext, ohne die Weitergabe abzubrechen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn