Using the heap in Golang to write a simple and efficient timer module

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Timer module is very important in the development of server, a high-performance timer module can greatly improve the efficiency of engine operation. Use Golang and heap to implement a common timer module, code from: Https://github.com/xiaonanln/goTimer

You can also view the documentation: Http://godoc.org/github.com/xiaonanln/goTimer, the complete code below, with appropriate annotations and analysis.

From the performance test results, the heap-based timer module is not much more efficient than the time-wheel (Timewheel) implementation, but it is much simpler in logic.

Source Code plus Comment:

Package Timerimport ("Container/heap"//Golang provides the heap library "FMT" "OS" "Runtime/debug" "Sync" "Time") const (Min_timer_ INTERVAL = 1 * time. Millisecond///cycle timer minimum interval) var (nextaddseq uint = 1//used to generate a unique incrementing ordinal for each timer object)//Timer object type timer struct {firetime time. Time//trigger times interval. Duration//Interval (for loop timer) callback Callbackfunc//callback function repeat bool//whether the loop cancelled BOOL//has canceled addseq UINT//sequence number} Canceling a timer, this timer will not be triggered by func (T *timer) cancel () {t.cancelled = true}//to determine if the timer has canceled func (T *timer) IsActive () bool {return! t.cancelled}//use a heap to manage the timer type _timerheap struct {timers []*timer}//Golang requires that the heap implement the following functions, meaning that the meanings of these functions are self-explanatory func ( H *_timerheap) Len () int {return Len (h.timers)}//uses the trigger time and needs to compare the timer to func (H *_timerheap) Less (i, J int) bool {//log. Println (H.timers[i].firetime, h.timers[j].firetime) t1, t2: = H.timers[i].firetime, H.timers[j].firetimeif t1. Before (T2) {return true}if t1. After (T2) {return false}//T1 = = t2, making sure Timer with same deadline was fired according to their add ORderreturn H.timers[i].addseq < H.timers[j].addseq}func (h *_timerheap) Swap (i, J int) {var tmp *timertmp = h.timers[i] H.timers[i] = H.timers[j]h.timers[j] = Tmp}func (H *_timerheap) Push (x interface{}) {h.timers = append (h.timers, x. (*Timer ))}func (H *_timerheap) Pop () (Ret interface{}) {L: = Len (h.timers) h.timers, ret = h.timers[:l-1], h.timers[l-1]return}// The type definition of the timer callback function is type Callbackfunc func () var (timerheap _timerheap//Timer heap Object Timerheaplock sync. Mutex//A global Lock) func init () {heap. Init (&AMP;TIMERHEAP)//Initialize timer heap}//set a one-time callback, this callback will be triggered after D, and call the callback function func Addcallback (d times. Duration, callback Callbackfunc) *timer {t: = &timer{firetime:time. Now (). ADD (d), interval:d,callback:callback,repeat:false,}timerheaplock.lock ()//use lock to circumvent race conditions T.addseq = Nextaddseq NextAddSeq + = 1heap. Push (&timerheap, T) timerheaplock.unlock () return t}//sets a timed-triggered callback that will be triggered the first time after D time, and then repeated every d time, and call the callback function Func AddTimer (d time. Duration, callback Callbackfunc) *timer {if D < min_timer_interval {d = min_timer_interval}t: = &timer{firetime:time. Now (). ADD (d), interval:d,callback:callback,repeat:true,//set to loop Timer}timerheaplock.lock () T.addseq = NEXTADDSEQ//Set ADDSEQ When Lockednextaddseq + = 1heap. Push (&timerheap, T) timerheaplock.unlock () return t}//to the Timer module once tick//// The general upper module needs to call the tick function at a certain time interval in the goroutine of a main thread to ensure that the timer triggers on time, and/or that all timer callbacks are run in this goroutine. Func Tick () {Now: = time. Now () Timerheaplock.lock () for {if Timerheap.len () <= 0 {//without any timers, return immediately to break}nextfiretime: = Timerheap.timers[0]. Firetimeif Nextfiretime.after (now) {//No timer to time, return break}t: = heap. Pop (&AMP;TIMERHEAP). (*timer) If t.cancelled {//Ignores canceled timers continue}if!t.repeat {t.cancelled = true}<strong>//must first be unlocked before invoking the timer's callback function, Otherwise it may lead to deadlock!!! </strong>timerheaplock.unlock () runcallback (t.callback)//Run callback function and capture Panictimerheaplock.lock () if t.repeat {// If it is a loop timer, put the timer back in the heap//add timer to Heapt.firetime = T.firetime.add (t.interval) if!t.firetime.after (now) { T.firetime = Now. AdD (t.interval)}t.addseq = nextaddseqnextaddseq + = 1heap. Push (&timerheap, T)}}timerheaplock.unlock ()}//creates a goroutine to timer module timing Tickfunc startticks (tickinterval time. Duration) {go selftickroutine (tickinterval)}func selftickroutine (tickinterval time. Duration) {for {time. The Sleep (tickinterval) Tick ()}}//runs the timer's callback function and captures the panic, converting panic to error output func Runcallback (callback Callbackfunc) {defer func ( {err: = recover () if err! = Nil {fmt. fprintf (OS. Stderr, "Callback%v paniced:%v\n", Callback, Err) Debug. Printstack ()}} () Callback ()}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.