Are the goruts launched in the goruts acceptable?

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.

+6
source share
2 answers

It's fine. It is quite acceptable to call gorutin from another gorutin. The calling goroutine will still come out, and the new goroutine will follow it in a fun way.

+11
source

Separating the new goroutine from the hortin is fine.

But I doubt that this is the simplest and cleanest solution to your problem. I assume that your first version did the obvious thing and pinged each URL in an endless loop. And these bites delay: deferred calls are executed after the function returns . (This has nothing to do with goroutine beeing "garbage collection, in fact goroutines just end and not collect.) In an infinite loop, you never return, you just accumulate pending calls that never run. That way, you never close all open res.Body, and you have run out of memory / something else and you will see a panic.

Doing defer res.Body.Close is a nice idiom, but not inside an infinite loop.

I would try your first version and immediately execute res.Body.Close on the nil error path.

+7
source

Source: https://habr.com/ru/post/943912/


All Articles