The time package provides two useful tools: Timer and Ticker.
Key differences:
Timer 'turns off' after it triggers, it needs to be reset (Reset) to be used again.Ticker generates events until explicitly stopped using the Stop() method.Usage features:
Stop() for Timer/Ticker when you are done to avoid resource leaks.Stop() on a Timer, it may be necessary to "drain" the channel: if the timer fired before Stop(), reading from the channel is mandatory.Example of correct Timer usage:
t := time.NewTimer(2 * time.Second) defer t.Stop() // mandatory! select { case <-t.C: fmt.Println("Time's up!") case <-otherDone: if !t.Stop() { <-t.C // drain the channel if needed } }
Can a Timer be reused immediately after receiving a value from the channel t.C? What happens if you don't call t.Stop()?
Answer: The timer should not be immediately reset without calling Stop() and possibly reading from the channel. If t.Stop() is not called, it may leave a "dead" goroutine or trigger unexpectedly in the next cycle (the channel is not cleared). Correct usage: call Stop(), and if Stop() returns false — definitely drain the channel by reading from t.C.
Story
Story
Ticker was used for periodic product updates, which was not stopped upon handler completion. The handler "hung" even after the user was deleted, continuing to consume CPU.Story
In tests, Stop() was not called for the timer — tests hung randomly because the timer's channel was not freed, waiting for a second "ping" from the timer, which never came.