Ich habe eine HTTP-Serveranwendung, die asynchrone Jobs verarbeitet.
-> Request --> Do async job with goroutine <- Response -------start goroutine------ -> Job1 -> Job1A -> Job1B -> Job2 -> Job3
Benutzer können asynchrone Jobs mit langer Laufzeit anfordern und die Anwendung antwortet sofort nach make goroutine auf die Anfrage.
Ich habe die Anforderungs-ID, das authentifizierte Token und die Benutzerinformationen in die context.Context
中。而且,我想把它放在 goroutine 下。但是,对请求 context
使用相同的 context
der Anforderung eingefügt, was zu einem unerwarteten Abbruch nach der Antwort führt, was nicht mein beabsichtigtes Verhalten ist.
Wie generiert man neue context
,独立于父请求 context
?或者,还有其他方法可以保证 context
mit allen Werten, ohne zu sterben, nachdem man die Antwort von Goroutine eingebracht hat?
Und eine Bonusfrage:
Stornierung vonJob1
~ Job3
应该被序列化,即 Job2
应该等待 Job1
和 Job3
等待 Job2
。并且,Job1A
和 Job1B
可以同时运行。如果我想传播给定 context
, wie kann ich ihren Pfad(?) stornieren? Sollte ich Select-Anweisungen für alle Funktionen überprüfen?
Ich verstehe, context
das Konzept der Stornierung und des vorzeitigen Ausstiegs zu propagieren, ohne sinnlose Aufgaben zu erledigen. Allerdings habe ich nicht herausgefunden, wie ich damit im Code umgehen soll. Ich würde mich freuen, wenn mir jemand beim Verständnis helfen könnte.
Der Wert im Kontext kann nicht ermittelt werden. Sie werden nicht als Karten, sondern als Kontextebenen gespeichert, wobei jede Ebene möglicherweise eine andere Implementierung der Speicherung von Werten bietet.
Wenn Sie jedoch wissen, welche Werte weitergegeben werden müssen, können Sie diese abfragen und mit diesen Werten einen neuen Kontext erstellen.
Das heißt, Sie können einen neuen Kontexttyp implementieren, der Werte aus einem anderen Kontext verwendet:
type newContext struct { context.Context values context.Context } func (c newContext) Value(key any) any { return c.values.Value(key) } ... newCtx:=newContext{ Context: context.Background(), values: ctx, }
Dabei wird der bestehende Wertekontext und ein neuer Kontext für alles andere genutzt.
Dann starten Sie eine neue Goroutine, um die Verarbeitung von Anfragen im neuen Kontext fortzusetzen.
Wenn Sie mehrere gleichzeitige Jobs erstellen möchten, können Sie dies in dieser Goroutine tun:
go func(ctx context.Context) { withCancel, cancel:=context.WithCancel(ctx) defer cancel() wg:=sync.WaitGroup{} wg.Add(2) go job1(withCancel,&wg) go job2(withCancel,&wg) wg.Wait() }(newCtx)
Auf diese Weise erhalten beide Jobs eine Stornierungsbenachrichtigung, wenn der Kontext abgebrochen wird. Wenn Sie den Abbruch von Job1 und Job2 separat steuern möchten:
go func(ctx context.Context) { withCancel1, cancel1:=context.WithCancel(ctx) defer cancel1() withCancel2, cancel2:=context.WithCancel(ctx) defer cancel2() wg:=sync.WaitGroup{} wg.Add(2) go job1(withCancel1,&wg) go job2(withCancel2,&wg) wg.Wait() }(newCtx)
Für aufeinanderfolgende Jobs (d. h. Job 3 endet nach Job 1) kombinieren Sie sie einfach so, dass sie wie ein einziger Job aussehen.
Um zu überprüfen, ob ein Kontext abgebrochen wurde, können Sie dies im Done
通道上执行 select
des Kontexts tun oder einfach Folgendes überprüfen:
if ctx.Err()!=nil { // Context canceled }
Das obige ist der detaillierte Inhalt vonGolang kopiert alle Kontextwerte. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!