This is a creation in Article, where the information may have evolved or changed.
In the go-to-band timer implementation, the usual minimum heap is used, which can be found here.
The minimum heap can provide good timing accuracy, but in the actual situation, we do not need such a high-precision timer, for example, for a connection, if it does not have data interaction within 2 minutes, we will delete it, 2 minutes does not need to be so accurate, a few seconds less than a few seconds does not matter.
Previously we implemented a single timingwheel, using the channel close way to deal with low-precision, ultra-large number of timer timing problems, see here.
But Timingwheel only after the interface, far from meeting the actual needs, so I follow the implementation of the Linux timer, according to gourd painting scoop, get a go version of the implementation. Linux timer implementation, refer to this article.
Later, I use Go timer to express my own implementation of the timer.
In Linux, we use tick to represent the time of an outage, using jiffies to indicate the number of ticks that have elapsed since the system was started. In Go timer, when we create a wheel, we need to specify the tick time, as follows:
func NewWheel(tick time.Duration) *Wheel
Wheel is the place where go timer is unified to manage the timer. For each tick, we use the ticker of go to simulate.
To facilitate external use, I still provide the same interface as Go's own timer, for example:
func NewTimer(d time.Duration) *Timer
In Newtimer, parameter D is a time duration, and we also need to calculate the tick to get the actual expires in Go timer, that is, how many times jiffies the timer triggers.
For example, if the newtimer parameter is 10s,tick 1s, then after 10 jiffies, the timer will time out to trigger. If the tick is 500ms, the timer will not be triggered until 20 jiffies is required.
So the timer timeout jiffies is calculated as follows:
expires = wheel.jiffies + d / wheel.tick
The detailed code is in Https://github.com/siddontang/golib/tree/master/timer.