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