123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
- //
- // 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,
- // You can obtain one at https://github.com/gogf/gf.
- package gtimer
- import (
- "github.com/gogf/gf/container/gtype"
- "time"
- )
- func New(options ...TimerOptions) *Timer {
- t := &Timer{
- queue: newPriorityQueue(),
- status: gtype.NewInt(StatusRunning),
- ticks: gtype.NewInt64(),
- }
- if len(options) > 0 {
- t.options = options[0]
- } else {
- t.options = DefaultOptions()
- }
- go t.loop()
- return t
- }
- // Add adds a timing job to the timer, which runs in interval of <interval>.
- func (t *Timer) Add(interval time.Duration, job JobFunc) *Entry {
- return t.createEntry(interval, job, false, -1, StatusReady)
- }
- // AddEntry adds a timing job to the timer with detailed parameters.
- //
- // 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.
- func (t *Timer) AddEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry {
- return t.createEntry(interval, job, singleton, times, status)
- }
- // AddSingleton is a convenience function for add singleton mode job.
- func (t *Timer) AddSingleton(interval time.Duration, job JobFunc) *Entry {
- return t.createEntry(interval, job, true, -1, StatusReady)
- }
- // AddOnce is a convenience function for adding a job which only runs once and then exits.
- func (t *Timer) AddOnce(interval time.Duration, job JobFunc) *Entry {
- return t.createEntry(interval, job, true, 1, StatusReady)
- }
- // AddTimes is a convenience function for adding a job which is limited running times.
- func (t *Timer) AddTimes(interval time.Duration, times int, job JobFunc) *Entry {
- return t.createEntry(interval, job, true, times, StatusReady)
- }
- // DelayAdd adds a timing job after delay of <interval> duration.
- // Also see Add.
- func (t *Timer) DelayAdd(delay time.Duration, interval time.Duration, job JobFunc) {
- t.AddOnce(delay, func() {
- t.Add(interval, job)
- })
- }
- // 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) {
- t.AddOnce(delay, func() {
- t.AddEntry(interval, job, singleton, times, status)
- })
- }
- // DelayAddSingleton adds a timing job after delay of <interval> duration.
- // Also see AddSingleton.
- func (t *Timer) DelayAddSingleton(delay time.Duration, interval time.Duration, job JobFunc) {
- t.AddOnce(delay, func() {
- t.AddSingleton(interval, job)
- })
- }
- // DelayAddOnce adds a timing job after delay of <interval> duration.
- // Also see AddOnce.
- func (t *Timer) DelayAddOnce(delay time.Duration, interval time.Duration, job JobFunc) {
- t.AddOnce(delay, func() {
- t.AddOnce(interval, job)
- })
- }
- // DelayAddTimes adds a timing job after delay of <interval> duration.
- // Also see AddTimes.
- func (t *Timer) DelayAddTimes(delay time.Duration, interval time.Duration, times int, job JobFunc) {
- t.AddOnce(delay, func() {
- t.AddTimes(interval, times, job)
- })
- }
- // Start starts the timer.
- func (t *Timer) Start() {
- t.status.Set(StatusRunning)
- }
- // Stop stops the timer.
- func (t *Timer) Stop() {
- t.status.Set(StatusStopped)
- }
- // Close closes the timer.
- func (t *Timer) Close() {
- t.status.Set(StatusClosed)
- }
- // 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 {
- var (
- infinite = false
- )
- if times <= 0 {
- infinite = true
- }
- 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
- }
- 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),
- }
- )
- t.queue.Push(entry, nextTicks)
- return entry
- }
|