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  }