Goroutines are a unusual and powerful programming language feature, so
they are a tempting toy to play with, and they get a bit overused.

There is some indication that the following Go principle holds true:

> Strive to provide synchronous APIs,<br>
> let the caller start goroutines.

To put this advice into a more concrete code example:

Do this:
```golang
func (t *type) Run(ctx context.Context) {
    // Implementation of background task
}
```

Instead of this:
```golang
func (t *type) Start() {
    t.wg.Add(1)
    go func() {
      // Implementation of background task
      t.wg.Done()
    }
}

func (t *type) Cancel() {
    // Somehow cancel the background task
    t.wg.Wait()
}
```

Upsides for `Run()`:

* The caller gets to decide how the "background" code gets run.
  * Spawning Goroutines is easy for the caller too.
  * `go` statements move towards the application's top-level.
    Goroutine coordination becomes simpler to reason about when
    goroutines are started in fewer places.
  * Callers can also run it without goroutine and just block on the
    call, if there is no other work to be done.
* Background task cancellation is provided through the context.
* Waiting for the background task has a trivial API (when the
  function returns), and can be done with the mechanism the
  caller prefers (waitgroups, channels, ...)
* It's on the safe side API-wise: There is no `Close()` method which
  callers can forget to call (leaking resources).

Another great discussion of this was in the [Go Time: On application
design](https://changelog.com/gotime/102#transcript-91) podcast
(starting around minute 47, Mat Ryer's explanation really resonated
with me)

**Addendum**: In the comments, Jacob is pointing out the talk ["Ways
To Do Things" by Peter
Bourgon](https://www.youtube.com/watch?v=LHe1Cb_Ud_M)
[(slides)](https://speakerdeck.com/peterbourgon/ways-to-do-things?slide=14),
who also appeared on the above "Go Time" episode. The talk describes
the `Run()` style quite clearly and in more detail. Thanks for the
excellent pointer, Jacob!
