Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is launching goroutines inside of goroutines acceptable?

Tags:

I'm learning Go right now using and one of my first projects is a simple ping script. Essentially I want to ping a bunch of urls, and on response of each one wait XXX number of seconds then ping again. Here is the abridged 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? } 

On my Get request I was previously calling defer res.Body.Close() but that was panicing after the app ran for awhile. I assumed that the defer could not call the Close() on the response until the goroutine had been garbage collected and the res no longer existed.

That got me thinking if by calling a goroutine inside of a goroutine was best practice or if I as causing the function to never exit, and then a defer would only be called once the goroutine was garbage collected.

like image 258
Alexander Rolek Avatar asked Apr 29 '13 20:04

Alexander Rolek


People also ask

Are Goroutines concurrent?

Goroutines are functions or methods that run concurrently with other functions or methods. Goroutines can be thought of as lightweight threads. The cost of creating a Goroutine is tiny when compared to a thread. Hence it's common for Go applications to have thousands of Goroutines running concurrently.

When should we use Goroutines?

Goroutines are useful when you want to do multiple things simultaneously. For example, if you have ten things you want to do at the same time, you can do each one on a separate goroutine, and wait for all of them to finish.

How do I get out of Goroutine gracefully?

Typically, you pass the goroutine a (possibly separate) signal channel. That signal channel is used to push a value into when you want the goroutine to stop. The goroutine polls that channel regularly. As soon as it detects a signal, it quits.

How do you know when a Goroutine is going to stop?

One goroutine can't forcibly stop another. To make a goroutine stoppable, let it listen for a stop signal on a dedicated quit channel, and check this channel at suitable points in your goroutine.


1 Answers

That is fine. It's perfectly acceptable to call a goroutine from another goroutine. The calling goroutine will still exit and the new goroutine will go on it's merry way.

like image 141
Jeremy Wall Avatar answered Oct 08 '22 22:10

Jeremy Wall