Skip to content

Instantly share code, notes, and snippets.

@mattetti
Last active April 16, 2023 03:09
Show Gist options
  • Save mattetti/3798173 to your computer and use it in GitHub Desktop.
Save mattetti/3798173 to your computer and use it in GitHub Desktop.
async fetching of urls using goroutines and channels
package main
import (
"fmt"
"net/http"
"time"
)
var urls = []string{
"https://splice.com/",
"https://golang.org/",
"https://matt.aimonetti.net/",
}
type HttpResponse struct {
url string
response *http.Response
err error
}
func asyncHttpGets(urls []string) []*HttpResponse {
ch := make(chan *HttpResponse, len(urls)) // buffered
responses := []*HttpResponse{}
for _, url := range urls {
go func(url string) {
fmt.Printf("Fetching %s \n", url)
resp, err := http.Get(url)
if err == nil {
resp.Body.Close()
}
ch <- &HttpResponse{url, resp, err}
}(url)
}
for {
select {
case r := <-ch:
fmt.Printf("%s was fetched\n", r.url)
responses = append(responses, r)
if len(responses) == len(urls) {
return responses
}
case <-time.After(50 * time.Millisecond):
fmt.Printf(".")
}
}
return responses
}
func main() {
results := asyncHttpGets(urls)
for _, result := range results {
if result.err != nil {
fmt.Printf("%s error: %v\n", result.url,
result.err)
continue
}
fmt.Printf("%s status: %s\n", result.url,
result.response.Status)
}
}
@mattetti
Copy link
Author

@DudeFactory I fixed the example, try with your domains now. The problem was that my quick fix was skipping writing to the channel in case of error so I didn't have to check if there was an error. The fix was to check for errors when reading from the channel and print the proper statement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment