github.com/gogf/gf@v1.16.9/os/gtimer/gtimer.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 implements timer for interval/delayed jobs running and management. 8 // 9 // This package is designed for management for millions of timing jobs. The differences 10 // between gtimer and gcron are as follows: 11 // 1. package gcron is implemented based on package gtimer. 12 // 2. gtimer is designed for high performance and for millions of timing jobs. 13 // 3. gcron supports configuration pattern grammar like linux crontab, which is more manually 14 // readable. 15 // 4. gtimer's benchmark OP is measured in nanoseconds, and gcron's benchmark OP is measured 16 // in microseconds. 17 // 18 // ALSO VERY NOTE the common delay of the timer: https://github.com/golang/go/issues/14410 19 package gtimer 20 21 import ( 22 "github.com/gogf/gf/container/gtype" 23 "sync" 24 "time" 25 26 "github.com/gogf/gf/os/gcmd" 27 ) 28 29 // Timer is the timer manager, which uses ticks to calculate the timing interval. 30 type Timer struct { 31 mu sync.RWMutex 32 queue *priorityQueue // queue is a priority queue based on heap structure. 33 status *gtype.Int // status is the current timer status. 34 ticks *gtype.Int64 // ticks is the proceeded interval number by the timer. 35 options TimerOptions // timer options is used for timer configuration. 36 } 37 38 // TimerOptions is the configuration object for Timer. 39 type TimerOptions struct { 40 Interval time.Duration // Interval is the interval escaped of the timer. 41 } 42 43 const ( 44 StatusReady = 0 // Job or Timer is ready for running. 45 StatusRunning = 1 // Job or Timer is already running. 46 StatusStopped = 2 // Job or Timer is stopped. 47 StatusClosed = -1 // Job or Timer is closed and waiting to be deleted. 48 panicExit = "exit" // panicExit is used for custom job exit with panic. 49 defaultTimerInterval = 100 // defaultTimerInterval is the default timer interval in milliseconds. 50 commandEnvKeyForInterval = "gf.gtimer.interval" // commandEnvKeyForInterval is the key for command argument or environment configuring default interval duration for timer. 51 ) 52 53 var ( 54 defaultTimer = New() 55 defaultInterval = gcmd.GetOptWithEnv(commandEnvKeyForInterval, defaultTimerInterval).Duration() * time.Millisecond 56 ) 57 58 // DefaultOptions creates and returns a default options object for Timer creation. 59 func DefaultOptions() TimerOptions { 60 return TimerOptions{ 61 Interval: defaultInterval, 62 } 63 } 64 65 // SetTimeout runs the job once after duration of <delay>. 66 // It is like the one in javascript. 67 func SetTimeout(delay time.Duration, job JobFunc) { 68 AddOnce(delay, job) 69 } 70 71 // SetInterval runs the job every duration of <delay>. 72 // It is like the one in javascript. 73 func SetInterval(interval time.Duration, job JobFunc) { 74 Add(interval, job) 75 } 76 77 // Add adds a timing job to the default timer, which runs in interval of <interval>. 78 func Add(interval time.Duration, job JobFunc) *Entry { 79 return defaultTimer.Add(interval, job) 80 } 81 82 // AddEntry adds a timing job to the default timer with detailed parameters. 83 // 84 // The parameter <interval> specifies the running interval of the job. 85 // 86 // The parameter <singleton> specifies whether the job running in singleton mode. 87 // There's only one of the same job is allowed running when its a singleton mode job. 88 // 89 // The parameter <times> specifies limit for the job running times, which means the job 90 // exits if its run times exceeds the <times>. 91 // 92 // The parameter <status> specifies the job status when it's firstly added to the timer. 93 func AddEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry { 94 return defaultTimer.AddEntry(interval, job, singleton, times, status) 95 } 96 97 // AddSingleton is a convenience function for add singleton mode job. 98 func AddSingleton(interval time.Duration, job JobFunc) *Entry { 99 return defaultTimer.AddSingleton(interval, job) 100 } 101 102 // AddOnce is a convenience function for adding a job which only runs once and then exits. 103 func AddOnce(interval time.Duration, job JobFunc) *Entry { 104 return defaultTimer.AddOnce(interval, job) 105 } 106 107 // AddTimes is a convenience function for adding a job which is limited running times. 108 func AddTimes(interval time.Duration, times int, job JobFunc) *Entry { 109 return defaultTimer.AddTimes(interval, times, job) 110 } 111 112 // DelayAdd adds a timing job after delay of <interval> duration. 113 // Also see Add. 114 func DelayAdd(delay time.Duration, interval time.Duration, job JobFunc) { 115 defaultTimer.DelayAdd(delay, interval, job) 116 } 117 118 // DelayAddEntry adds a timing job after delay of <interval> duration. 119 // Also see AddEntry. 120 func DelayAddEntry(delay time.Duration, interval time.Duration, job JobFunc, singleton bool, times int, status int) { 121 defaultTimer.DelayAddEntry(delay, interval, job, singleton, times, status) 122 } 123 124 // DelayAddSingleton adds a timing job after delay of <interval> duration. 125 // Also see AddSingleton. 126 func DelayAddSingleton(delay time.Duration, interval time.Duration, job JobFunc) { 127 defaultTimer.DelayAddSingleton(delay, interval, job) 128 } 129 130 // DelayAddOnce adds a timing job after delay of <interval> duration. 131 // Also see AddOnce. 132 func DelayAddOnce(delay time.Duration, interval time.Duration, job JobFunc) { 133 defaultTimer.DelayAddOnce(delay, interval, job) 134 } 135 136 // DelayAddTimes adds a timing job after delay of <interval> duration. 137 // Also see AddTimes. 138 func DelayAddTimes(delay time.Duration, interval time.Duration, times int, job JobFunc) { 139 defaultTimer.DelayAddTimes(delay, interval, times, job) 140 } 141 142 // Exit is used in timing job internally, which exits and marks it closed from timer. 143 // The timing job will be automatically removed from timer later. It uses "panic-recover" 144 // mechanism internally implementing this feature, which is designed for simplification 145 // and convenience. 146 func Exit() { 147 panic(panicExit) 148 }