Heim  >  Artikel  >  Backend-Entwicklung  >  Wie gehe ich bei der Überprüfung der URL-Erreichbarkeit richtig mit Zeitüberschreitungen bei Kanälen in Go um?

Wie gehe ich bei der Überprüfung der URL-Erreichbarkeit richtig mit Zeitüberschreitungen bei Kanälen in Go um?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-20 02:18:02856Durchsuche

How to Properly Handle Timeouts with Channels in Go When Checking URL Reachability?

Umgang mit Zeitüberschreitungen bei Kanälen in Go

Problem:

Bei der Verwendung von Goroutinen und Kanälen Überprüfen Sie die Erreichbarkeit einer Liste von URLs. Die Timeout-Bedingung scheint nicht ausgeführt zu werden. Dies führt dazu, dass der Code immer „true“ zurückgibt, auch wenn einige URLs nicht erreichbar sind.

Analyse:

Das Problem liegt in der Implementierung der check(u)-Funktion, die bewirkt, dass das Timeout nie ausgeführt wird. In Ihrem Code wird die check(u)-Funktion in der aktuellen Goroutine ausgeführt und blockiert die Ausführung der select-Anweisung in IsReachable. Wenn die Select-Anweisung entsperrt ist, sind sowohl der check(u)- als auch der time.After(time.Second)-Kanal zum Verbrauch bereit und die Laufzeit kann einen der beiden auswählen.

Lösung 1:

Um dieses Problem zu beheben, können Sie die Funktion check(u) separat ausführen goroutine:

package main

import "fmt"
import "time"

func check(u string, checked chan<- bool) {
    time.Sleep(4 * time.Second)
    checked <- true
}

func IsReachable(urls []string) bool {

    ch := make(chan bool, 1)
    for _, url := range urls {
        go func(u string) {
            checked := make(chan bool)
            go check(u, checked)
            select {
            case ret := <-checked:
                ch <- ret
            case <-time.After(1 * time.Second):
                ch <- false
            }
        }(url)
    }
    return <-ch
}

func main() {
    fmt.Println(IsReachable([]string{"url1"}))
}

In diesem modifizierten Code wird die check(u)-Funktion in einer Goroutine ausgeführt und das Ergebnis an den überprüften Kanal übergeben. Die Select-Anweisung in IsReachable wartet nun darauf, dass entweder der überprüfte Kanal oder der Timeout-Kanal bereit wird. Dadurch wird sichergestellt, dass die Timeout-Bedingung korrekt behandelt wird.

Lösung 2:

Alternativ können Sie den Code vereinfachen, indem Sie ein einziges Timeout für alle URLs festlegen. Dieser Ansatz ist machbar, wenn das Timeout im Vergleich zur Zeit, die zum Erstellen von Goroutinen benötigt wird, ausreichend lang ist:

package main

import "fmt"
import "time"

func check(u string, ch chan<- bool) {
    time.Sleep(4 * time.Second)
    ch <- true
}

func IsReachable(urls []string) bool {
    ch := make(chan bool, len(urls))
    for _, url := range urls {
        go check(url, ch)
    }
    time.AfterFunc(time.Second, func() { ch <- false })
    return <-ch
}
func main() {
    fmt.Println(IsReachable([]string{"url1", "url2"}))
}

In diesem Code wird ein einziges Timeout für alle URLs festgelegt, die time.AfterFunc verwenden. Wenn eine URL innerhalb des Timeout-Zeitraums erreichbar ist, erhält der CH-Kanal „true“ und die Funktion gibt „true“ zurück. Andernfalls wird false an ch gesendet und die Funktion gibt false zurück.

Das obige ist der detaillierte Inhalt vonWie gehe ich bei der Überprüfung der URL-Erreichbarkeit richtig mit Zeitüberschreitungen bei Kanälen in Go um?. 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