gtimer.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. // Package gtimer implements timer for interval/delayed jobs running and management.
  7. //
  8. // This package is designed for management for millions of timing jobs. The differences
  9. // between gtimer and gcron are as follows:
  10. // 1. package gcron is implemented based on package gtimer.
  11. // 2. gtimer is designed for high performance and for millions of timing jobs.
  12. // 3. gcron supports configuration pattern grammar like linux crontab, which is more manually
  13. // readable.
  14. // 4. gtimer's benchmark OP is measured in nanoseconds, and gcron's benchmark OP is measured
  15. // in microseconds.
  16. //
  17. // ALSO VERY NOTE the common delay of the timer: https://github.com/golang/go/issues/14410
  18. package gtimer
  19. import (
  20. "github.com/gogf/gf/container/gtype"
  21. "sync"
  22. "time"
  23. "github.com/gogf/gf/os/gcmd"
  24. )
  25. // Timer is the timer manager, which uses ticks to calculate the timing interval.
  26. type Timer struct {
  27. mu sync.RWMutex
  28. queue *priorityQueue // queue is a priority queue based on heap structure.
  29. status *gtype.Int // status is the current timer status.
  30. ticks *gtype.Int64 // ticks is the proceeded interval number by the timer.
  31. options TimerOptions // timer options is used for timer configuration.
  32. }
  33. // TimerOptions is the configuration object for Timer.
  34. type TimerOptions struct {
  35. Interval time.Duration // Interval is the interval escaped of the timer.
  36. }
  37. const (
  38. StatusReady = 0 // Job or Timer is ready for running.
  39. StatusRunning = 1 // Job or Timer is already running.
  40. StatusStopped = 2 // Job or Timer is stopped.
  41. StatusClosed = -1 // Job or Timer is closed and waiting to be deleted.
  42. panicExit = "exit" // panicExit is used for custom job exit with panic.
  43. defaultTimerInterval = 100 // defaultTimerInterval is the default timer interval in milliseconds.
  44. commandEnvKeyForInterval = "gf.gtimer.interval" // commandEnvKeyForInterval is the key for command argument or environment configuring default interval duration for timer.
  45. )
  46. var (
  47. defaultTimer = New()
  48. defaultInterval = gcmd.GetOptWithEnv(commandEnvKeyForInterval, defaultTimerInterval).Duration() * time.Millisecond
  49. )
  50. // DefaultOptions creates and returns a default options object for Timer creation.
  51. func DefaultOptions() TimerOptions {
  52. return TimerOptions{
  53. Interval: defaultInterval,
  54. }
  55. }
  56. // SetTimeout runs the job once after duration of <delay>.
  57. // It is like the one in javascript.
  58. func SetTimeout(delay time.Duration, job JobFunc) {
  59. AddOnce(delay, job)
  60. }
  61. // SetInterval runs the job every duration of <delay>.
  62. // It is like the one in javascript.
  63. func SetInterval(interval time.Duration, job JobFunc) {
  64. Add(interval, job)
  65. }
  66. // Add adds a timing job to the default timer, which runs in interval of <interval>.
  67. func Add(interval time.Duration, job JobFunc) *Entry {
  68. return defaultTimer.Add(interval, job)
  69. }
  70. // AddEntry adds a timing job to the default timer with detailed parameters.
  71. //
  72. // The parameter <interval> specifies the running interval of the job.
  73. //
  74. // The parameter <singleton> specifies whether the job running in singleton mode.
  75. // There's only one of the same job is allowed running when its a singleton mode job.
  76. //
  77. // The parameter <times> specifies limit for the job running times, which means the job
  78. // exits if its run times exceeds the <times>.
  79. //
  80. // The parameter <status> specifies the job status when it's firstly added to the timer.
  81. func AddEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry {
  82. return defaultTimer.AddEntry(interval, job, singleton, times, status)
  83. }
  84. // AddSingleton is a convenience function for add singleton mode job.
  85. func AddSingleton(interval time.Duration, job JobFunc) *Entry {
  86. return defaultTimer.AddSingleton(interval, job)
  87. }
  88. // AddOnce is a convenience function for adding a job which only runs once and then exits.
  89. func AddOnce(interval time.Duration, job JobFunc) *Entry {
  90. return defaultTimer.AddOnce(interval, job)
  91. }
  92. // AddTimes is a convenience function for adding a job which is limited running times.
  93. func AddTimes(interval time.Duration, times int, job JobFunc) *Entry {
  94. return defaultTimer.AddTimes(interval, times, job)
  95. }
  96. // DelayAdd adds a timing job after delay of <interval> duration.
  97. // Also see Add.
  98. func DelayAdd(delay time.Duration, interval time.Duration, job JobFunc) {
  99. defaultTimer.DelayAdd(delay, interval, job)
  100. }
  101. // DelayAddEntry adds a timing job after delay of <interval> duration.
  102. // Also see AddEntry.
  103. func DelayAddEntry(delay time.Duration, interval time.Duration, job JobFunc, singleton bool, times int, status int) {
  104. defaultTimer.DelayAddEntry(delay, interval, job, singleton, times, status)
  105. }
  106. // DelayAddSingleton adds a timing job after delay of <interval> duration.
  107. // Also see AddSingleton.
  108. func DelayAddSingleton(delay time.Duration, interval time.Duration, job JobFunc) {
  109. defaultTimer.DelayAddSingleton(delay, interval, job)
  110. }
  111. // DelayAddOnce adds a timing job after delay of <interval> duration.
  112. // Also see AddOnce.
  113. func DelayAddOnce(delay time.Duration, interval time.Duration, job JobFunc) {
  114. defaultTimer.DelayAddOnce(delay, interval, job)
  115. }
  116. // DelayAddTimes adds a timing job after delay of <interval> duration.
  117. // Also see AddTimes.
  118. func DelayAddTimes(delay time.Duration, interval time.Duration, times int, job JobFunc) {
  119. defaultTimer.DelayAddTimes(delay, interval, times, job)
  120. }
  121. // Exit is used in timing job internally, which exits and marks it closed from timer.
  122. // The timing job will be automatically removed from timer later. It uses "panic-recover"
  123. // mechanism internally implementing this feature, which is designed for simplification
  124. // and convenience.
  125. func Exit() {
  126. panic(panicExit)
  127. }