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  }