I study. Come on now and one of my first projects is a simple ping script. Essentially, I want to ping a bunch of URLs, and when each of them answers, wait XXX seconds, and then ping again. Here is the abbreviated code:
func main() { // read our text file of urls f, err := ioutil.ReadFile(urlFile) if err != nil { log.Print(err) } urlStrings := []string{} urlStrings = strings.Split(string(f), "\n") for _, v := range urlStrings { go ping(v) } // output logs to the terminal // channel is global for i := range c { fmt.Println(i) } } func ping(url string) { // for our lag timer start := time.Now() // make our request _, err := http.Get(url) if err != nil { msg := url + " Error:" + err.Error() fmt.Println(msg) c <- msg reportError(msg) } else { lag := time.Since(start) var msg string // running slow if lag > lagThreshold*time.Second { msg = url + " lag: " + lag.String() reportError(msg) } msg = url + ", lag: " + lag.String() c <- msg } time.Sleep(pingInterval * time.Second) go ping(url) // is this acceptable? }
In my Get request, I previously called defer res.Body.Close (), but it was freezing after the application started for a while. I suggested that deferment cannot call Close () to respond until goroutine has garbage collected and res no longer exists.
It made me wonder if calling a goroutine inside a goroutine was best practice or if I call a function to never exit, and then a delay will be called only after the goroutine is garbage collected.
source share