github.com/gogf/gf/v2@v2.7.4/os/gtimer/gtimer_timer_loop.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gtimer 8 9 import "time" 10 11 // loop starts the ticker using a standalone goroutine. 12 func (t *Timer) loop() { 13 var ( 14 currentTimerTicks int64 15 timerIntervalTicker = time.NewTicker(t.options.Interval) 16 ) 17 defer timerIntervalTicker.Stop() 18 for { 19 select { 20 case <-timerIntervalTicker.C: 21 // Check the timer status. 22 switch t.status.Val() { 23 case StatusRunning: 24 // Timer proceeding. 25 if currentTimerTicks = t.ticks.Add(1); currentTimerTicks >= t.queue.NextPriority() { 26 t.proceed(currentTimerTicks) 27 } 28 29 case StatusStopped: 30 // Do nothing. 31 32 case StatusClosed: 33 // Timer exits. 34 return 35 } 36 } 37 } 38 } 39 40 // proceed function proceeds the timer job checking and running logic. 41 func (t *Timer) proceed(currentTimerTicks int64) { 42 var value interface{} 43 for { 44 value = t.queue.Pop() 45 if value == nil { 46 break 47 } 48 entry := value.(*Entry) 49 // It checks if it meets the ticks' requirement. 50 if jobNextTicks := entry.nextTicks.Val(); currentTimerTicks < jobNextTicks { 51 // It pushes the job back if current ticks does not meet its running ticks requirement. 52 t.queue.Push(entry, entry.nextTicks.Val()) 53 break 54 } 55 // It checks the job running requirements and then does asynchronous running. 56 entry.doCheckAndRunByTicks(currentTimerTicks) 57 // Status check: push back or ignore it. 58 if entry.Status() != StatusClosed { 59 // It pushes the job back to queue for next running. 60 t.queue.Push(entry, entry.nextTicks.Val()) 61 } 62 } 63 }