gtimer.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Copyright GoFrame Author(https://github.com/gogf/gf). 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 Hierarchical Timing Wheel for interval/delayed jobs
  7. // 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. import (
  21. "fmt"
  22. "math"
  23. "time"
  24. "github.com/gogf/gf/os/gcmd"
  25. )
  26. const (
  27. StatusReady = 0 // Job is ready for running.
  28. StatusRunning = 1 // Job is already running.
  29. StatusStopped = 2 // Job is stopped.
  30. StatusReset = 3 // Job is reset.
  31. StatusClosed = -1 // Job is closed and waiting to be deleted.
  32. panicExit = "exit" // Internal usage for custom job exit function with panic.
  33. defaultTimes = math.MaxInt32 // Default limit running times, a big number.
  34. defaultSlotNumber = 10 // Default slot number.
  35. defaultWheelInterval = 50 // Default wheel interval.
  36. defaultWheelLevel = 5 // Default wheel level.
  37. cmdEnvKey = "gf.gtimer" // Configuration key for command argument or environment.
  38. )
  39. var (
  40. defaultSlots = gcmd.GetWithEnv(fmt.Sprintf("%s.slots", cmdEnvKey), defaultSlotNumber).Int()
  41. defaultLevel = gcmd.GetWithEnv(fmt.Sprintf("%s.level", cmdEnvKey), defaultWheelLevel).Int()
  42. defaultInterval = gcmd.GetWithEnv(fmt.Sprintf("%s.interval", cmdEnvKey), defaultWheelInterval).Duration() * time.Millisecond
  43. defaultTimer = New(defaultSlots, defaultInterval, defaultLevel)
  44. )
  45. // SetTimeout runs the job once after duration of <delay>.
  46. // It is like the one in javascript.
  47. func SetTimeout(delay time.Duration, job JobFunc) {
  48. AddOnce(delay, job)
  49. }
  50. // SetInterval runs the job every duration of <delay>.
  51. // It is like the one in javascript.
  52. func SetInterval(interval time.Duration, job JobFunc) {
  53. Add(interval, job)
  54. }
  55. // Add adds a timing job to the default timer, which runs in interval of <interval>.
  56. func Add(interval time.Duration, job JobFunc) *Entry {
  57. return defaultTimer.Add(interval, job)
  58. }
  59. // AddEntry adds a timing job to the default timer with detailed parameters.
  60. //
  61. // The parameter <interval> specifies the running interval of the job.
  62. //
  63. // The parameter <singleton> specifies whether the job running in singleton mode.
  64. // There's only one of the same job is allowed running when its a singleton mode job.
  65. //
  66. // The parameter <times> specifies limit for the job running times, which means the job
  67. // exits if its run times exceeds the <times>.
  68. //
  69. // The parameter <status> specifies the job status when it's firstly added to the timer.
  70. func AddEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry {
  71. return defaultTimer.AddEntry(interval, job, singleton, times, status)
  72. }
  73. // AddSingleton is a convenience function for add singleton mode job.
  74. func AddSingleton(interval time.Duration, job JobFunc) *Entry {
  75. return defaultTimer.AddSingleton(interval, job)
  76. }
  77. // AddOnce is a convenience function for adding a job which only runs once and then exits.
  78. func AddOnce(interval time.Duration, job JobFunc) *Entry {
  79. return defaultTimer.AddOnce(interval, job)
  80. }
  81. // AddTimes is a convenience function for adding a job which is limited running times.
  82. func AddTimes(interval time.Duration, times int, job JobFunc) *Entry {
  83. return defaultTimer.AddTimes(interval, times, job)
  84. }
  85. // DelayAdd adds a timing job after delay of <interval> duration.
  86. // Also see Add.
  87. func DelayAdd(delay time.Duration, interval time.Duration, job JobFunc) {
  88. defaultTimer.DelayAdd(delay, interval, job)
  89. }
  90. // DelayAddEntry adds a timing job after delay of <interval> duration.
  91. // Also see AddEntry.
  92. func DelayAddEntry(delay time.Duration, interval time.Duration, job JobFunc, singleton bool, times int, status int) {
  93. defaultTimer.DelayAddEntry(delay, interval, job, singleton, times, status)
  94. }
  95. // DelayAddSingleton adds a timing job after delay of <interval> duration.
  96. // Also see AddSingleton.
  97. func DelayAddSingleton(delay time.Duration, interval time.Duration, job JobFunc) {
  98. defaultTimer.DelayAddSingleton(delay, interval, job)
  99. }
  100. // DelayAddOnce adds a timing job after delay of <interval> duration.
  101. // Also see AddOnce.
  102. func DelayAddOnce(delay time.Duration, interval time.Duration, job JobFunc) {
  103. defaultTimer.DelayAddOnce(delay, interval, job)
  104. }
  105. // DelayAddTimes adds a timing job after delay of <interval> duration.
  106. // Also see AddTimes.
  107. func DelayAddTimes(delay time.Duration, interval time.Duration, times int, job JobFunc) {
  108. defaultTimer.DelayAddTimes(delay, interval, times, job)
  109. }
  110. // Exit is used in timing job internally, which exits and marks it closed from timer.
  111. // The timing job will be automatically removed from timer later. It uses "panic-recover"
  112. // mechanism internally implementing this feature, which is designed for simplification
  113. // and convenience.
  114. func Exit() {
  115. panic(panicExit)
  116. }