github.com/wangyougui/gf/v2@v2.6.5/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/wangyougui/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 go func() { 14 var ( 15 currentTimerTicks int64 16 timerIntervalTicker = time.NewTicker(t.options.Interval) 17 ) 18 defer timerIntervalTicker.Stop() 19 for { 20 select { 21 case <-timerIntervalTicker.C: 22 // Check the timer status. 23 switch t.status.Val() { 24 case StatusRunning: 25 // Timer proceeding. 26 if currentTimerTicks = t.ticks.Add(1); currentTimerTicks >= t.queue.NextPriority() { 27 t.proceed(currentTimerTicks) 28 } 29 30 case StatusStopped: 31 // Do nothing. 32 33 case StatusClosed: 34 // Timer exits. 35 return 36 } 37 } 38 } 39 }() 40 } 41 42 // proceed function proceeds the timer job checking and running logic. 43 func (t *Timer) proceed(currentTimerTicks int64) { 44 var ( 45 value interface{} 46 ) 47 for { 48 value = t.queue.Pop() 49 if value == nil { 50 break 51 } 52 entry := value.(*Entry) 53 // It checks if it meets the ticks' requirement. 54 if jobNextTicks := entry.nextTicks.Val(); currentTimerTicks < jobNextTicks { 55 // It pushes the job back if current ticks does not meet its running ticks requirement. 56 t.queue.Push(entry, entry.nextTicks.Val()) 57 break 58 } 59 // It checks the job running requirements and then does asynchronous running. 60 entry.doCheckAndRunByTicks(currentTimerTicks) 61 // Status check: push back or ignore it. 62 if entry.Status() != StatusClosed { 63 // It pushes the job back to queue for next running. 64 t.queue.Push(entry, entry.nextTicks.Val()) 65 } 66 } 67 }