typestar

Graceful shutdown in Go

A done channel, closed once, tells every worker to stop.

func workUntilDone(jobs <-chan int, done <-chan struct{}) []int {
    var (
        mu      sync.Mutex
        handled []int
        wg      sync.WaitGroup
    )

    for range 3 {
        wg.Go(func() {
            for {
                select {
                case job, ok := <-jobs:
                    if !ok {
                        return
                    }
                    mu.Lock()
                    handled = append(handled, job)
                    mu.Unlock()
                case <-done:
                    return
                }
            }
        })
    }

    wg.Wait()
    return handled
}

How it works

  1. Closing a channel broadcasts: every receiver wakes.
  2. Workers select on their work and on done.
  3. Wait for them before returning, or you leak goroutines.

Keywords and builtins used here

The run, in numbers

Lines
28
Characters to type
326
Tokens
100
Three-star pace
110 tpm

At the three-star pace of 110 tokens a minute, this run takes about 55 seconds.

Type this snippet

Step 5 of 5 in Patterns, step 23 of 25 in Concurrency.

← Previous Next →