github.com/gogf/gf@v1.16.9/os/gtimer/gtimer_timer.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 ( 10 "github.com/gogf/gf/container/gtype" 11 "time" 12 ) 13 14 func New(options ...TimerOptions) *Timer { 15 t := &Timer{ 16 queue: newPriorityQueue(), 17 status: gtype.NewInt(StatusRunning), 18 ticks: gtype.NewInt64(), 19 } 20 if len(options) > 0 { 21 t.options = options[0] 22 } else { 23 t.options = DefaultOptions() 24 } 25 go t.loop() 26 return t 27 } 28 29 // Add adds a timing job to the timer, which runs in interval of <interval>. 30 func (t *Timer) Add(interval time.Duration, job JobFunc) *Entry { 31 return t.createEntry(interval, job, false, -1, StatusReady) 32 } 33 34 // AddEntry adds a timing job to the timer with detailed parameters. 35 // 36 // The parameter <interval> specifies the running interval of the job. 37 // 38 // The parameter <singleton> specifies whether the job running in singleton mode. 39 // There's only one of the same job is allowed running when its a singleton mode job. 40 // 41 // The parameter <times> specifies limit for the job running times, which means the job 42 // exits if its run times exceeds the <times>. 43 // 44 // The parameter <status> specifies the job status when it's firstly added to the timer. 45 func (t *Timer) AddEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry { 46 return t.createEntry(interval, job, singleton, times, status) 47 } 48 49 // AddSingleton is a convenience function for add singleton mode job. 50 func (t *Timer) AddSingleton(interval time.Duration, job JobFunc) *Entry { 51 return t.createEntry(interval, job, true, -1, StatusReady) 52 } 53 54 // AddOnce is a convenience function for adding a job which only runs once and then exits. 55 func (t *Timer) AddOnce(interval time.Duration, job JobFunc) *Entry { 56 return t.createEntry(interval, job, true, 1, StatusReady) 57 } 58 59 // AddTimes is a convenience function for adding a job which is limited running times. 60 func (t *Timer) AddTimes(interval time.Duration, times int, job JobFunc) *Entry { 61 return t.createEntry(interval, job, true, times, StatusReady) 62 } 63 64 // DelayAdd adds a timing job after delay of <interval> duration. 65 // Also see Add. 66 func (t *Timer) DelayAdd(delay time.Duration, interval time.Duration, job JobFunc) { 67 t.AddOnce(delay, func() { 68 t.Add(interval, job) 69 }) 70 } 71 72 // DelayAddEntry adds a timing job after delay of <interval> duration. 73 // Also see AddEntry. 74 func (t *Timer) DelayAddEntry(delay time.Duration, interval time.Duration, job JobFunc, singleton bool, times int, status int) { 75 t.AddOnce(delay, func() { 76 t.AddEntry(interval, job, singleton, times, status) 77 }) 78 } 79 80 // DelayAddSingleton adds a timing job after delay of <interval> duration. 81 // Also see AddSingleton. 82 func (t *Timer) DelayAddSingleton(delay time.Duration, interval time.Duration, job JobFunc) { 83 t.AddOnce(delay, func() { 84 t.AddSingleton(interval, job) 85 }) 86 } 87 88 // DelayAddOnce adds a timing job after delay of <interval> duration. 89 // Also see AddOnce. 90 func (t *Timer) DelayAddOnce(delay time.Duration, interval time.Duration, job JobFunc) { 91 t.AddOnce(delay, func() { 92 t.AddOnce(interval, job) 93 }) 94 } 95 96 // DelayAddTimes adds a timing job after delay of <interval> duration. 97 // Also see AddTimes. 98 func (t *Timer) DelayAddTimes(delay time.Duration, interval time.Duration, times int, job JobFunc) { 99 t.AddOnce(delay, func() { 100 t.AddTimes(interval, times, job) 101 }) 102 } 103 104 // Start starts the timer. 105 func (t *Timer) Start() { 106 t.status.Set(StatusRunning) 107 } 108 109 // Stop stops the timer. 110 func (t *Timer) Stop() { 111 t.status.Set(StatusStopped) 112 } 113 114 // Close closes the timer. 115 func (t *Timer) Close() { 116 t.status.Set(StatusClosed) 117 } 118 119 // createEntry creates and adds a timing job to the timer. 120 func (t *Timer) createEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry { 121 var ( 122 infinite = false 123 ) 124 if times <= 0 { 125 infinite = true 126 } 127 var ( 128 intervalTicksOfJob = int64(interval / t.options.Interval) 129 ) 130 if intervalTicksOfJob == 0 { 131 // If the given interval is lesser than the one of the wheel, 132 // then sets it to one tick, which means it will be run in one interval. 133 intervalTicksOfJob = 1 134 } 135 var ( 136 nextTicks = t.ticks.Val() + intervalTicksOfJob 137 entry = &Entry{ 138 job: job, 139 timer: t, 140 ticks: intervalTicksOfJob, 141 times: gtype.NewInt(times), 142 status: gtype.NewInt(status), 143 singleton: gtype.NewBool(singleton), 144 nextTicks: gtype.NewInt64(nextTicks), 145 infinite: gtype.NewBool(infinite), 146 } 147 ) 148 t.queue.Push(entry, nextTicks) 149 return entry 150 }