Skip to content

Latest commit

 

History

History
77 lines (61 loc) · 1.45 KB

goroutine-init.md

File metadata and controls

77 lines (61 loc) · 1.45 KB

No goroutines in init()

init() functions should not spawn goroutines. See also Avoid init().

If a package has need of a background goroutine, it must expose an object that is responsible for managing a goroutine's lifetime. The object must provide a method (Close, Stop, Shutdown, etc) that signals the background goroutine to stop, and waits for it to exit.

BadGood
func init() {
  go doWork()
}

func doWork() {
  for {
    // ...
  }
}
type Worker struct{ /* ... */ }

func NewWorker(...) *Worker {
  w := &Worker{
    stop: make(chan struct{}),
    done: make(chan struct{}),
    // ...
  }
  go w.doWork()
}

func (w *Worker) doWork() {
  defer close(w.done)
  for {
    // ...
    case <-w.stop:
      return
  }
}

// Shutdown tells the worker to stop
// and waits until it has finished.
func (w *Worker) Shutdown() {
  close(w.stop)
  <-w.done
}

Spawns a background goroutine unconditionally when the user exports this package. The user has no control over the goroutine or a means of stopping it.

Spawns the worker only if the user requests it. Provides a means of shutting down the worker so that the user can free up resources used by the worker.

Note that you should use WaitGroups if the worker manages multiple goroutines. See Wait for goroutines to exit.