Proposal Details
I propose the new rule about time.Ticker. Here is the example code.
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
fmt.Println(runtime.NumGoroutine())
t := Proc(time.Second)
t.Stop()
time.Sleep(5 * time.Second)
fmt.Println(runtime.NumGoroutine())
}
func Proc(d time.Duration) *time.Ticker {
t := time.NewTicker(d)
go func() {
for {
select {
case <-t.C:
fmt.Println("tick")
}
}
}()
return t
}
This program must leak goroutine because it can't cancel the goroutine Proc generates. Ticker doesn't have the structure to cancel and I think primary Go developer may misread Stop is for canceling the Ticker.
Comment From: gabyhelp
Related Issues and Documentation
- time: document that time.Tick causes a resource leak #11662 (closed)
- time: stop time.Ticker when it is garbage collected #8001 (closed)
- proposal: time: Add TickerFunc #68482
- proposal: time: add a channel to time.Ticker to detect stopped tickers #35643 (closed)
- proposal: Go 2: time: deprecate time.Tick(d Duration) #37144 (closed)
- proposal: cmd/vet: report time.Tick and time.NewTicker scoped to select statements #48170 (closed)
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: seankhliao
For a check to be added to cmd/vet, we'd need evidence that the pattern it catches is common enough to be worth checking for, and has no false positives. I don't think this will meet that those requirements. I'd recommend starting with a third party linter, and we can reevaluate when we see sufficient adoption.