goodtimer
Golang timer for humans.
goodtimer
is a thin wrapper around the standard time.Timer, and it tries to play two roles:
- A library that helps you use time.Timer more easily.
- As well as a demonstration that shows you how to use time.Timer correctly.
Installation
$ go get -u github.com/RussellLuo/goodtimer
Documentation
For usage and examples see the Godoc.
Why?!
TL;DR: The standard time.Timer is hard to use correctly.
Timer.Stop
Per the documentation of Timer.Stop, to stop the timer created with NewTimer, you need to check the return value and drain the channel if necessary:
if !t.Stop() {
<-t.C
}
But the draining operation will be blocked if the the program has already received from the Timer's channel before. So someone suggests doing a non-blocking draining:
if !t.Stop() {
select {
case <-t.C: // try to drain the channel
default:
}
}
However, there is a race condition between draining the channel and sending time into the channel, which may lead to a undrained channel.
Timer.Reset
To reset a timer, is must have expired or be stopped before. So Timer.Reset has almost the same issue with Timer.Stop.
Solutions
Finally, as Russ Cox suggested (here and here), the correct way to use time.Timer is:
- All the Timer operations (Timer.Stop, Timer.Reset and receiving from or draining the channel) should be done in the same goroutine.
- The program should manage an extra status showing whether it has received from the Timer's channel or not.