Skip to content

Prevent Goroutine Leak

Alex Tan Hong Pin edited this page Apr 1, 2018 · 1 revision

With Context

// main.go

// We create a default context here
ctx := context.Background()

// Then we create a cancellation context here
ctx, cancel := context.WithCancel(ctx)

// When the program terminates, we will send a cancel signal to all the goroutines
defer cancel()

someFunc := func (ctx context.Context, in chan<- interface{}) <-chan interface{} {
  out := make(chan interface{})
  go func() {
    defer close(out)
    for i := range in {
      select {
        // When the cancel signal is received, the goroutine will be terminated,
        // preventing any goroutine leaks
        case <-ctx.Done():
          return
        case out <- i:
      }
    }
  }()
  return out
}

With Done

// main.go

done := make(chan interface{})
defer close(done)

someFunc := func (done, in chan<- interface{}) <-chan interface{} {
  out := make(chan interface{})
  go func() {
    defer close(out)
    for i := range in {
      select {
        // When the cancel signal is received, the goroutine will be terminated,
        // preventing any goroutine leaks
        case <-done:
          return
        case out <- i:
      }
    }
  }()
  return out
}
Clone this wiki locally