Skip to content

Instantly share code, notes, and snippets.

@mbecker
Created October 14, 2019 16:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbecker/f281c9f6f07b2b7beb5f6b6048cd14b8 to your computer and use it in GitHub Desktop.
Save mbecker/f281c9f6f07b2b7beb5f6b6048cd14b8 to your computer and use it in GitHub Desktop.
Restart Goroutine
package main
import "fmt"
// number of desired workers
const nWorkers = 10
func main() {
// make a buffered channel with the space for my 10 workers
workerChan := make(chan *worker, nWorkers)
for i := 0; i < nWorkers; i++ {
i := i
wk := &worker{id: i}
go wk.work(workerChan)
}
// read the channel, it will block until something is written, then a new
// goroutine will start
for wk := range workerChan {
// log the error
fmt.Printf("Worker %d stopped with err: %s", wk.id, wk.err)
// reset err
wk.err = nil
// a goroutine has ended, restart it
go wk.work(workerChan)
}
}
type worker struct {
id int
err error
}
func (wk *worker) work(workerChan chan<- *worker) (err error) {
// make my goroutine signal its death, wether it's a panic or a return
defer func() {
if r := recover(); r != nil {
if err, ok := r.(error); ok {
wk.err = err
} else {
wk.err = fmt.Errorf("Panic happened with %v", r)
}
} else {
wk.err = err
}
workerChan <- wk
}()
// do something
// ...
return err
}
# https://stackoverflow.com/questions/55273965/how-to-know-if-goroutine-still-exist
# The best way is not to know if it's till alive but to know when it dies so you can restart it.
# You can do that by setting a defer with a recover on your goroutine which would write to a channel signaling the death of the goroutine. Then on the main goroutine, you read from that channel, and whenever something is read, you restart a goroutine. You could identify wich goroutine failed by returning a struct containing the goroutine id and the error.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment