I have a simple implementation that uses context.WithTimeout
, more or less like:
ctx, cancelFn := context.WithTimeout(context.Background(), time.Duration(time.Minute*1))
go func() {
// do something
cancelFn()
}()
select {
case <-ctx.Done():
// ...
return
}
When I monitor the number of currently existing goroutines (using runtime.NumGoroutines()
), it seems that whenever the WithTimeout()
function gets called, it internally creates a goroutine to keep track of the time and eventually cancel the context (which makes sense, if you look at the internals (https://github.com/golang/go/blob/master/src/context/context.go#L401 and https://github.com/golang/go/blob/master/src/time/sleep.go#L170).
However, when the context is finished and the case statement is reached, the goroutine is not being released. It seems that it keeps running forever and the resources are not released properly.
If I change the implementation to use a simpler version of a timeout, without the context.WithTimeout()
, more or less like:
select {
case <-time.After(time.Minute*1):
// ...
return
}
Then the number of goroutines is the expected in the first place and nothing seems to leak.
What could be the problem? What am I missing?