2021-01-17 21:46:25 +08:00
|
|
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
2019-01-12 22:41:12 +08:00
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
2019-02-02 16:18:25 +08:00
|
|
|
// You can obtain one at https://github.com/gogf/gf.
|
2019-01-12 22:41:12 +08:00
|
|
|
|
|
|
|
package gtimer
|
|
|
|
|
|
|
|
import (
|
2021-10-11 21:41:56 +08:00
|
|
|
"github.com/gogf/gf/v2/container/gtype"
|
2021-05-15 18:13:51 +08:00
|
|
|
"time"
|
2019-01-12 22:41:12 +08:00
|
|
|
)
|
|
|
|
|
2021-05-15 18:13:51 +08:00
|
|
|
func New(options ...TimerOptions) *Timer {
|
2019-06-19 09:06:52 +08:00
|
|
|
t := &Timer{
|
2021-05-15 18:13:51 +08:00
|
|
|
queue: newPriorityQueue(),
|
|
|
|
status: gtype.NewInt(StatusRunning),
|
|
|
|
ticks: gtype.NewInt64(),
|
2019-06-19 09:06:52 +08:00
|
|
|
}
|
2021-05-15 18:13:51 +08:00
|
|
|
if len(options) > 0 {
|
|
|
|
t.options = options[0]
|
|
|
|
} else {
|
|
|
|
t.options = DefaultOptions()
|
2019-06-19 09:06:52 +08:00
|
|
|
}
|
2021-05-15 18:13:51 +08:00
|
|
|
go t.loop()
|
2019-06-19 09:06:52 +08:00
|
|
|
return t
|
2019-01-12 22:41:12 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// Add adds a timing job to the timer, which runs in interval of <interval>.
|
2021-05-26 09:55:33 +08:00
|
|
|
func (t *Timer) Add(interval time.Duration, job JobFunc) *Entry {
|
2021-08-20 14:09:15 +08:00
|
|
|
return t.createEntry(interval, job, false, -1, StatusReady)
|
2019-01-21 22:09:51 +08:00
|
|
|
}
|
|
|
|
|
2021-05-26 09:55:33 +08:00
|
|
|
// AddEntry adds a timing job to the timer with detailed parameters.
|
2020-01-21 14:46:23 +08:00
|
|
|
//
|
|
|
|
// The parameter <interval> specifies the running interval of the job.
|
|
|
|
//
|
|
|
|
// The parameter <singleton> specifies whether the job running in singleton mode.
|
|
|
|
// There's only one of the same job is allowed running when its a singleton mode job.
|
|
|
|
//
|
|
|
|
// The parameter <times> specifies limit for the job running times, which means the job
|
|
|
|
// exits if its run times exceeds the <times>.
|
|
|
|
//
|
|
|
|
// The parameter <status> specifies the job status when it's firstly added to the timer.
|
2021-05-26 09:55:33 +08:00
|
|
|
func (t *Timer) AddEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry {
|
|
|
|
return t.createEntry(interval, job, singleton, times, status)
|
2019-01-12 22:41:12 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// AddSingleton is a convenience function for add singleton mode job.
|
2021-05-26 09:55:33 +08:00
|
|
|
func (t *Timer) AddSingleton(interval time.Duration, job JobFunc) *Entry {
|
2021-08-20 14:09:15 +08:00
|
|
|
return t.createEntry(interval, job, true, -1, StatusReady)
|
2019-01-12 22:41:12 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// AddOnce is a convenience function for adding a job which only runs once and then exits.
|
2021-05-26 09:55:33 +08:00
|
|
|
func (t *Timer) AddOnce(interval time.Duration, job JobFunc) *Entry {
|
|
|
|
return t.createEntry(interval, job, true, 1, StatusReady)
|
2019-01-12 22:41:12 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// AddTimes is a convenience function for adding a job which is limited running times.
|
2021-05-26 09:55:33 +08:00
|
|
|
func (t *Timer) AddTimes(interval time.Duration, times int, job JobFunc) *Entry {
|
|
|
|
return t.createEntry(interval, job, true, times, StatusReady)
|
2019-01-12 22:41:12 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// DelayAdd adds a timing job after delay of <interval> duration.
|
|
|
|
// Also see Add.
|
2019-01-12 22:41:12 +08:00
|
|
|
func (t *Timer) DelayAdd(delay time.Duration, interval time.Duration, job JobFunc) {
|
2019-06-19 09:06:52 +08:00
|
|
|
t.AddOnce(delay, func() {
|
|
|
|
t.Add(interval, job)
|
|
|
|
})
|
2019-01-12 22:41:12 +08:00
|
|
|
}
|
|
|
|
|
2021-05-26 09:55:33 +08:00
|
|
|
// DelayAddEntry adds a timing job after delay of <interval> duration.
|
|
|
|
// Also see AddEntry.
|
|
|
|
func (t *Timer) DelayAddEntry(delay time.Duration, interval time.Duration, job JobFunc, singleton bool, times int, status int) {
|
2019-06-19 09:06:52 +08:00
|
|
|
t.AddOnce(delay, func() {
|
2021-05-26 09:55:33 +08:00
|
|
|
t.AddEntry(interval, job, singleton, times, status)
|
2019-06-19 09:06:52 +08:00
|
|
|
})
|
2019-01-21 22:09:51 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// DelayAddSingleton adds a timing job after delay of <interval> duration.
|
|
|
|
// Also see AddSingleton.
|
2019-01-12 22:41:12 +08:00
|
|
|
func (t *Timer) DelayAddSingleton(delay time.Duration, interval time.Duration, job JobFunc) {
|
2019-06-19 09:06:52 +08:00
|
|
|
t.AddOnce(delay, func() {
|
|
|
|
t.AddSingleton(interval, job)
|
|
|
|
})
|
2019-01-12 22:41:12 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// DelayAddOnce adds a timing job after delay of <interval> duration.
|
|
|
|
// Also see AddOnce.
|
2019-01-12 22:41:12 +08:00
|
|
|
func (t *Timer) DelayAddOnce(delay time.Duration, interval time.Duration, job JobFunc) {
|
2019-06-19 09:06:52 +08:00
|
|
|
t.AddOnce(delay, func() {
|
|
|
|
t.AddOnce(interval, job)
|
|
|
|
})
|
2019-01-12 22:41:12 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// DelayAddTimes adds a timing job after delay of <interval> duration.
|
|
|
|
// Also see AddTimes.
|
2019-01-12 22:41:12 +08:00
|
|
|
func (t *Timer) DelayAddTimes(delay time.Duration, interval time.Duration, times int, job JobFunc) {
|
2019-06-19 09:06:52 +08:00
|
|
|
t.AddOnce(delay, func() {
|
|
|
|
t.AddTimes(interval, times, job)
|
|
|
|
})
|
2019-01-12 22:41:12 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// Start starts the timer.
|
2019-01-17 14:15:23 +08:00
|
|
|
func (t *Timer) Start() {
|
2020-12-14 13:26:48 +08:00
|
|
|
t.status.Set(StatusRunning)
|
2019-01-17 14:15:23 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// Stop stops the timer.
|
2019-01-17 14:15:23 +08:00
|
|
|
func (t *Timer) Stop() {
|
2020-12-14 13:26:48 +08:00
|
|
|
t.status.Set(StatusStopped)
|
2019-01-17 14:15:23 +08:00
|
|
|
}
|
|
|
|
|
2020-01-21 14:46:23 +08:00
|
|
|
// Close closes the timer.
|
2019-01-12 22:41:12 +08:00
|
|
|
func (t *Timer) Close() {
|
2020-12-14 13:26:48 +08:00
|
|
|
t.status.Set(StatusClosed)
|
2019-01-12 22:41:12 +08:00
|
|
|
}
|
|
|
|
|
2021-05-26 09:55:33 +08:00
|
|
|
// createEntry creates and adds a timing job to the timer.
|
|
|
|
func (t *Timer) createEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry {
|
2021-08-20 11:52:22 +08:00
|
|
|
var (
|
|
|
|
infinite = false
|
|
|
|
)
|
2021-05-15 18:13:51 +08:00
|
|
|
if times <= 0 {
|
2021-08-20 11:52:22 +08:00
|
|
|
infinite = true
|
2019-06-19 09:06:52 +08:00
|
|
|
}
|
2021-05-15 18:13:51 +08:00
|
|
|
var (
|
|
|
|
intervalTicksOfJob = int64(interval / t.options.Interval)
|
|
|
|
)
|
|
|
|
if intervalTicksOfJob == 0 {
|
|
|
|
// If the given interval is lesser than the one of the wheel,
|
|
|
|
// then sets it to one tick, which means it will be run in one interval.
|
|
|
|
intervalTicksOfJob = 1
|
|
|
|
}
|
2021-08-20 11:52:22 +08:00
|
|
|
var (
|
|
|
|
nextTicks = t.ticks.Val() + intervalTicksOfJob
|
|
|
|
entry = &Entry{
|
|
|
|
job: job,
|
|
|
|
timer: t,
|
|
|
|
ticks: intervalTicksOfJob,
|
|
|
|
times: gtype.NewInt(times),
|
|
|
|
status: gtype.NewInt(status),
|
|
|
|
singleton: gtype.NewBool(singleton),
|
|
|
|
nextTicks: gtype.NewInt64(nextTicks),
|
|
|
|
infinite: gtype.NewBool(infinite),
|
|
|
|
}
|
|
|
|
)
|
2021-05-26 09:55:33 +08:00
|
|
|
t.queue.Push(entry, nextTicks)
|
|
|
|
return entry
|
2019-06-19 09:06:52 +08:00
|
|
|
}
|