schedule.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package otherutils
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. type event struct {
  7. timer *time.Timer
  8. ticker *time.Ticker
  9. endtime time.Time
  10. duration time.Duration
  11. parameter interface{}
  12. }
  13. func (e *event) expire() bool {
  14. if e.timer != nil {
  15. select {
  16. case <-e.timer.C:
  17. return true
  18. default:
  19. }
  20. }
  21. if e.ticker != nil {
  22. select {
  23. case <-e.ticker.C:
  24. return true
  25. default:
  26. }
  27. }
  28. return false
  29. }
  30. // Scheduler 调度程序
  31. type Scheduler interface {
  32. OnTimer(id int, parameter interface{})
  33. }
  34. // Schedule 时间表
  35. // 定时时间精确到秒,不精确管理goroutine的退出
  36. // 目前只用来管理房间
  37. type Schedule struct {
  38. scheduler Scheduler
  39. mutex sync.Mutex
  40. events map[int]*event
  41. }
  42. // NewSchedule 创建时间表
  43. func NewSchedule(scheduler Scheduler) *Schedule {
  44. return &Schedule{
  45. scheduler: scheduler,
  46. events: make(map[int]*event),
  47. }
  48. }
  49. // Start 开始
  50. func (s *Schedule) Start() {
  51. for {
  52. time.Sleep(time.Second)
  53. s.mutex.Lock()
  54. for k, v := range s.events {
  55. if v.expire() {
  56. if v.timer != nil {
  57. delete(s.events, k)
  58. }
  59. if v.ticker != nil {
  60. v.endtime = v.endtime.Add(v.duration)
  61. }
  62. go s.scheduler.OnTimer(k, v.parameter)
  63. }
  64. }
  65. s.mutex.Unlock()
  66. }
  67. }
  68. // Add 添加
  69. func (s *Schedule) Add(id int, duration time.Duration, parameter interface{}, persistence bool) {
  70. s.mutex.Lock()
  71. defer s.mutex.Unlock()
  72. ev, ok := s.events[id]
  73. if ok {
  74. if ev.timer == nil {
  75. return
  76. }
  77. if !ev.timer.Stop() {
  78. <-ev.timer.C // 必须这样做,不然Reset之后有可能立刻到期
  79. }
  80. ev.timer.Reset(duration)
  81. } else {
  82. ev = new(event)
  83. s.events[id] = ev
  84. if !persistence {
  85. ev.timer = time.NewTimer(duration)
  86. } else {
  87. ev.ticker = time.NewTicker(duration)
  88. }
  89. }
  90. ev.duration = duration
  91. ev.parameter = parameter
  92. ev.endtime = time.Now().Add(duration)
  93. }
  94. // Remove 移除
  95. func (s *Schedule) Remove(id int) {
  96. s.mutex.Lock()
  97. defer s.mutex.Unlock()
  98. if ev, ok := s.events[id]; ok {
  99. if ev.timer != nil && !ev.timer.Stop() {
  100. <-ev.timer.C
  101. }
  102. if ev.ticker != nil {
  103. ev.ticker.Stop()
  104. }
  105. delete(s.events, id)
  106. }
  107. }
  108. // Surplus 剩余
  109. func (s *Schedule) Surplus(id int) (duration time.Duration) {
  110. s.mutex.Lock()
  111. defer s.mutex.Unlock()
  112. if ev, ok := s.events[id]; ok {
  113. duration = ev.endtime.Sub(time.Now())
  114. }
  115. if duration < 0 {
  116. duration = 0
  117. }
  118. return
  119. }