gtimer_timer.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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
  7. import (
  8. "github.com/gogf/gf/container/gtype"
  9. "time"
  10. )
  11. func New(options ...TimerOptions) *Timer {
  12. t := &Timer{
  13. queue: newPriorityQueue(),
  14. status: gtype.NewInt(StatusRunning),
  15. ticks: gtype.NewInt64(),
  16. }
  17. if len(options) > 0 {
  18. t.options = options[0]
  19. } else {
  20. t.options = DefaultOptions()
  21. }
  22. go t.loop()
  23. return t
  24. }
  25. // Add adds a timing job to the timer, which runs in interval of <interval>.
  26. func (t *Timer) Add(interval time.Duration, job JobFunc) *Entry {
  27. return t.createEntry(interval, job, false, -1, StatusReady)
  28. }
  29. // AddEntry adds a timing job to the timer with detailed parameters.
  30. //
  31. // The parameter <interval> specifies the running interval of the job.
  32. //
  33. // The parameter <singleton> specifies whether the job running in singleton mode.
  34. // There's only one of the same job is allowed running when its a singleton mode job.
  35. //
  36. // The parameter <times> specifies limit for the job running times, which means the job
  37. // exits if its run times exceeds the <times>.
  38. //
  39. // The parameter <status> specifies the job status when it's firstly added to the timer.
  40. func (t *Timer) AddEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry {
  41. return t.createEntry(interval, job, singleton, times, status)
  42. }
  43. // AddSingleton is a convenience function for add singleton mode job.
  44. func (t *Timer) AddSingleton(interval time.Duration, job JobFunc) *Entry {
  45. return t.createEntry(interval, job, true, -1, StatusReady)
  46. }
  47. // AddOnce is a convenience function for adding a job which only runs once and then exits.
  48. func (t *Timer) AddOnce(interval time.Duration, job JobFunc) *Entry {
  49. return t.createEntry(interval, job, true, 1, StatusReady)
  50. }
  51. // AddTimes is a convenience function for adding a job which is limited running times.
  52. func (t *Timer) AddTimes(interval time.Duration, times int, job JobFunc) *Entry {
  53. return t.createEntry(interval, job, true, times, StatusReady)
  54. }
  55. // DelayAdd adds a timing job after delay of <interval> duration.
  56. // Also see Add.
  57. func (t *Timer) DelayAdd(delay time.Duration, interval time.Duration, job JobFunc) {
  58. t.AddOnce(delay, func() {
  59. t.Add(interval, job)
  60. })
  61. }
  62. // DelayAddEntry adds a timing job after delay of <interval> duration.
  63. // Also see AddEntry.
  64. func (t *Timer) DelayAddEntry(delay time.Duration, interval time.Duration, job JobFunc, singleton bool, times int, status int) {
  65. t.AddOnce(delay, func() {
  66. t.AddEntry(interval, job, singleton, times, status)
  67. })
  68. }
  69. // DelayAddSingleton adds a timing job after delay of <interval> duration.
  70. // Also see AddSingleton.
  71. func (t *Timer) DelayAddSingleton(delay time.Duration, interval time.Duration, job JobFunc) {
  72. t.AddOnce(delay, func() {
  73. t.AddSingleton(interval, job)
  74. })
  75. }
  76. // DelayAddOnce adds a timing job after delay of <interval> duration.
  77. // Also see AddOnce.
  78. func (t *Timer) DelayAddOnce(delay time.Duration, interval time.Duration, job JobFunc) {
  79. t.AddOnce(delay, func() {
  80. t.AddOnce(interval, job)
  81. })
  82. }
  83. // DelayAddTimes adds a timing job after delay of <interval> duration.
  84. // Also see AddTimes.
  85. func (t *Timer) DelayAddTimes(delay time.Duration, interval time.Duration, times int, job JobFunc) {
  86. t.AddOnce(delay, func() {
  87. t.AddTimes(interval, times, job)
  88. })
  89. }
  90. // Start starts the timer.
  91. func (t *Timer) Start() {
  92. t.status.Set(StatusRunning)
  93. }
  94. // Stop stops the timer.
  95. func (t *Timer) Stop() {
  96. t.status.Set(StatusStopped)
  97. }
  98. // Close closes the timer.
  99. func (t *Timer) Close() {
  100. t.status.Set(StatusClosed)
  101. }
  102. // createEntry creates and adds a timing job to the timer.
  103. func (t *Timer) createEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry {
  104. var (
  105. infinite = false
  106. )
  107. if times <= 0 {
  108. infinite = true
  109. }
  110. var (
  111. intervalTicksOfJob = int64(interval / t.options.Interval)
  112. )
  113. if intervalTicksOfJob == 0 {
  114. // If the given interval is lesser than the one of the wheel,
  115. // then sets it to one tick, which means it will be run in one interval.
  116. intervalTicksOfJob = 1
  117. }
  118. var (
  119. nextTicks = t.ticks.Val() + intervalTicksOfJob
  120. entry = &Entry{
  121. job: job,
  122. timer: t,
  123. ticks: intervalTicksOfJob,
  124. times: gtype.NewInt(times),
  125. status: gtype.NewInt(status),
  126. singleton: gtype.NewBool(singleton),
  127. nextTicks: gtype.NewInt64(nextTicks),
  128. infinite: gtype.NewBool(infinite),
  129. }
  130. )
  131. t.queue.Push(entry, nextTicks)
  132. return entry
  133. }