Reputation: 7
I have the following website status checker code in Go:
package main
import (
"fmt"
"net/http"
)
func main() {
ls := []string{
"http://google.com",
"http://facebook.com",
"http://amazon.com",
"http://golang.org",
}
c := make(chan string)
for _, url := range ls{
go checkStatus(url,c)
}
fmt.Println(<- c)
fmt.Println(<- c)
fmt.Println(<- c)
fmt.Println(<- c)
fmt.Println(<- c)
}
func checkStatus(url string, ch chan string) {
_, err := http.Get(url)
if err!=nil{
fmt.Println(url,"not working fine")
ch <- "might be down!!"
return
}
fmt.Println(url, "is up!!!")
ch <- "It is up"
}
Here, I have 5 receivers but 4 senders. Ideally the code should throw an error. But here it is simply blocking indefinitely.
But the below code is throwing error:
package main
import (
"fmt"
)
func main() {
channel := make(chan string)
for i:=0;i<2;i++{
go func1(i, channel)
}
fmt.Println(<- channel)
fmt.Println(<- channel)
fmt.Println(<- channel)
}
func func1(i int,c chan string){
if i%2==0{
c <- fmt.Sprintf("Holaa %v",i)
return
}
c <- fmt.Sprintf("Hello %v",i)
}
Here i have 3 receivers for 2 senders. This is throwing error as expected.
My question is:
Why the first program is not throwing error but the second one does? Even though the number of receivers in both the programs are greater than the number of senders
Upvotes: -5
Views: 57
Reputation: 6215
That's not a channel issue, but rather a behavior of the deadlock detection.
When you make an http
call, it will spawn internal goroutines which will prevent the detection system from accusing the deadlock. It thinks it's possible for one of the goroutines to still send something on the channel.
To better observe this, you can set the iddle connection timeout:
func checkStatus(url string, ch chan string) {
client := &http.Client{
Transport: &http.Transport{
IdleConnTimeout: 5 * time.Second, // Make the cleanup faster
},
}
resp, err := client.Get(url)
if err != nil {
fmt.Println(url, "not working fine")
ch <- "might be down!!"
return
}
defer resp.Body.Close() // btw, you were missing this
fmt.Println(url, "is up!!!")
ch <- "It is up"
}
After 5s, you'll see the deadlock crash:
fatal error: all goroutines are asleep - deadlock!
Upvotes: 0