gtimer_timer_loop.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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 "time"
  8. // loop starts the ticker using a standalone goroutine.
  9. func (t *Timer) loop() {
  10. go func() {
  11. var (
  12. currentTimerTicks int64
  13. timerIntervalTicker = time.NewTicker(t.options.Interval)
  14. )
  15. defer timerIntervalTicker.Stop()
  16. for {
  17. select {
  18. case <-timerIntervalTicker.C:
  19. // Check the timer status.
  20. switch t.status.Val() {
  21. case StatusRunning:
  22. // Timer proceeding.
  23. if currentTimerTicks = t.ticks.Add(1); currentTimerTicks >= t.queue.NextPriority() {
  24. t.proceed(currentTimerTicks)
  25. }
  26. case StatusStopped:
  27. // Do nothing.
  28. case StatusClosed:
  29. // Timer exits.
  30. return
  31. }
  32. }
  33. }
  34. }()
  35. }
  36. // proceed function proceeds the timer job checking and running logic.
  37. func (t *Timer) proceed(currentTimerTicks int64) {
  38. var (
  39. value interface{}
  40. )
  41. for {
  42. value = t.queue.Pop()
  43. if value == nil {
  44. break
  45. }
  46. entry := value.(*Entry)
  47. // It checks if it meets the ticks' requirement.
  48. if jobNextTicks := entry.nextTicks.Val(); currentTimerTicks < jobNextTicks {
  49. // It pushes the job back if current ticks does not meet its running ticks requirement.
  50. t.queue.Push(entry, entry.nextTicks.Val())
  51. break
  52. }
  53. // It checks the job running requirements and then does asynchronous running.
  54. entry.doCheckAndRunByTicks(currentTimerTicks)
  55. // Status check: push back or ignore it.
  56. if entry.Status() != StatusClosed {
  57. // It pushes the job back to queue for next running.
  58. t.queue.Push(entry, entry.nextTicks.Val())
  59. }
  60. }
  61. }