Why does the goroutine only run once as part of a waitgroup

Issue

func check(name string) string {
    resp, err := http.Get(endpoint + name)
    if err != nil {
        panic(err)
    }

    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)

    if err != nil {
        panic(err)
    }

    return string(body)

}

func worker(name string, wg *sync.WaitGroup, names chan string) {
    defer wg.Done()
    var a = check(name)
    names <- a
}

func main() {
    names := make(chan string)
    var wg sync.WaitGroup

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go worker("www"+strconv.Itoa(i), &wg, names)
    }
    fmt.Println(<-names)
}

The expected result would be 5 results but, only one executes and the process ends.
Is there something I am missing? New to go.
The endpoint is a generic API that returns json

Solution

You started 5 goroutines, but read input for one only. Also, you are not waiting for your goroutines to end.

// If there are only 5 goroutines unconditionally, you don't need the wg
for i := 1; i <= 5; i++ {
        go worker("www"+strconv.Itoa(i),  names)
}
for i:=1;i<=5;i++ {
   fmt.Println(<-names)
}

If, however, you don’t know how many goroutines you’re waiting, then the waitgroup is necessary.

for i := 1; i <= 5; i++ {
      wg.Add(1)
      go worker("www"+strconv.Itoa(i), &wg, names)
}
// Read from the channel until it is closed
done:=make(chan struct{})
go func() {
   for x:=range names {
     fmt.Println(x)
    }
    // Signal that println is completed
    close(done)
}()

// Wait for goroutines to end
wg.Wait()
// Close the channel to terminate the reader goroutine
close(names)
// Wait until println completes
<-done

Answered By – Burak Serdar

Answer Checked By – Marilyn (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.