Heim > Backend-Entwicklung > Golang > Wie können wir die Kontextaufhebungspriorität in der „select'-Anweisung von Go garantieren?

Wie können wir die Kontextaufhebungspriorität in der „select'-Anweisung von Go garantieren?

DDD
Freigeben: 2024-12-20 02:09:13
Original
363 Leute haben es durchsucht

How Can We Guarantee Context Cancellation Priority in Go's `select` Statement?

Priorisierung der Go-select-Anweisung

Problem:

In einer Go-select-Anweisung die Reihenfolge Die Auswertung für Fallblöcke ist nicht deterministisch. Dies kann zu Situationen führen, in denen ein bestimmter Fallblock nicht sofort eingegeben wird, selbst wenn der entsprechende Kanal empfangsbereit ist.

Szenario:

Erwägen Sie eine sendRegularHeartbeats() Funktion, die regelmäßig Heartbeat-Nachrichten sendet und beendet wird, wenn ihr Kontext abgebrochen wird. Wenn der Kontext abgebrochen wird, bevor die erste Heartbeat-Nachricht gesendet wird, gehen wir davon aus, dass keine Heartbeat-Nachrichten übertragen werden.

Problem mit nichtdeterministischer Auswertung:

In einigen Fällen , wird eine Heartbeat-Nachricht gesendet, obwohl der Kontext vor dem Start der Funktion abgebrochen wurde. Dies liegt daran, dass die Reihenfolge der Auswertung unvorhersehbar ist und der Standard- oder Heartbeat-Fall vor dem Kontextfall eingegeben werden kann.

Falscher Vorschlag:

Eine vorgeschlagene Lösung ist um eine „isContextclosed“-Prüfung im Heartbeat-Fall hinzuzufügen. Dies ist jedoch keine zuverlässige Lösung, da sowohl der Kontext- als auch der Heartbeat-Kanal gleichzeitig zum Lesen bereit sein können.

Vorgeschlagene Lösung: Primordial Select

Um den Kontextfall zu priorisieren können wir eine ursprüngliche Select-Anweisung einführen, die prüft, ob der Kontextkanal bereit ist. Nur wenn der Kontextkanal nicht bereit ist, wird die zweite Select-Anweisung ausgeführt.

func sendRegularHeartbeats(ctx context.Context) {
    for {
        // Primordial select: Check for context channel being ready only.
        select {
        case <-ctx.Done():
            return
        default:
        }

        // Secondary select: Handle heartbeat logic.
        select {
        case <-ctx.Done():
            return
        case <-time.After(1 * time.Second):
            sendHeartbeat()
        }
    }
}
Nach dem Login kopieren

Unvollkommenheit:

Während dieser Ansatz den Kontextfall effektiv priorisiert, kann es sein, dass dies der Fall ist ermöglichen immer noch „nahe genug“-Ereignisse. Wenn beispielsweise ein Heartbeat-Ereignis kurz nach der Bereitschaft des Kontextkanals eintrifft, kann das Heartbeat gesendet werden, bevor der Kontextfall eingegeben wird. Mit der aktuellen Go-Sprachimplementierung gibt es keine perfekte Lösung für dieses Problem.

Das obige ist der detaillierte Inhalt vonWie können wir die Kontextaufhebungspriorität in der „select'-Anweisung von Go garantieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage