sngmatchhistory.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package sngmatch
  2. import (
  3. "bet24.com/log"
  4. "bet24.com/redis"
  5. "encoding/json"
  6. "strconv"
  7. "sync"
  8. "time"
  9. )
  10. const max_history_sec = 86400 * 3 // 最多存储时长
  11. const refresh_history_config_sec = 600
  12. func getRedisKey() string {
  13. return "sngmatch:history"
  14. }
  15. type historyMgr struct {
  16. isDirty bool
  17. lock *sync.RWMutex
  18. histories []snghistory
  19. }
  20. var hm *historyMgr
  21. func getHistoryManager() *historyMgr {
  22. if hm == nil {
  23. hm = new(historyMgr)
  24. hm.lock = &sync.RWMutex{}
  25. }
  26. return hm
  27. }
  28. func (hm *historyMgr) run() {
  29. hm.loadHistoryFromRedis()
  30. hm.flush()
  31. }
  32. func (m *historyMgr) loadHistoryFromRedis() {
  33. data, ok := redis.String_Get(getRedisKey())
  34. if data == "" || !ok {
  35. return
  36. }
  37. m.lock.Lock()
  38. err := json.Unmarshal([]byte(data), &m.histories)
  39. m.lock.Unlock()
  40. if err != nil {
  41. log.Release("sngmatch.historyMgr.loadHistoryFromRedis Unmarshal failed err:%v,%s", err, data)
  42. return
  43. }
  44. }
  45. func (m *historyMgr) checkTimeout() {
  46. now := time.Now().Unix()
  47. removeIndex := 0
  48. m.lock.RLock()
  49. for i := 0; i < len(m.histories); i++ {
  50. removeIndex = i
  51. if now-m.histories[i].EndTime < max_history_sec {
  52. break
  53. }
  54. }
  55. m.lock.RUnlock()
  56. if removeIndex == 0 {
  57. return
  58. }
  59. log.Release("sngmatch.historymgr.checkTimeout removeIndex = %d", removeIndex)
  60. m.lock.Lock()
  61. m.isDirty = true
  62. m.histories = m.histories[removeIndex:]
  63. m.lock.Unlock()
  64. }
  65. func (m *historyMgr) forceFlush() {
  66. m.isDirty = true
  67. m.doFlush()
  68. }
  69. func (m *historyMgr) flush() {
  70. time.AfterFunc(refresh_history_config_sec*time.Second, m.flush)
  71. m.checkTimeout()
  72. if !m.isDirty {
  73. return
  74. }
  75. m.doFlush()
  76. }
  77. func (m *historyMgr) doFlush() {
  78. m.lock.RLock()
  79. m.isDirty = false
  80. d, _ := json.Marshal(m.histories)
  81. m.lock.RUnlock()
  82. go redis.String_Set(getRedisKey(), string(d))
  83. }
  84. func (hm *historyMgr) dump(param2 string) {
  85. log.Release("-------------------------------")
  86. log.Release("sngmatch.historyMgr.dump[%s]", param2)
  87. defer func() {
  88. log.Release("+++++++++++++++++++++++++++++++")
  89. log.Release("")
  90. }()
  91. if param2 == "" {
  92. hm.lock.RLock()
  93. for _, v := range hm.histories {
  94. v.dump(false)
  95. }
  96. hm.lock.RUnlock()
  97. return
  98. }
  99. matchNo, err := strconv.Atoi(param2)
  100. if err != nil {
  101. log.Release(" atoi error %v", err)
  102. return
  103. }
  104. hm.lock.RLock()
  105. for _, v := range hm.histories {
  106. if v.MatchNo == matchNo {
  107. v.dump(true)
  108. }
  109. }
  110. hm.lock.RUnlock()
  111. }
  112. func (hm *historyMgr) getHistory(userId int) string {
  113. var ret []snghistory
  114. hm.lock.RLock()
  115. for _, v := range hm.histories {
  116. if v.isUserEnrolled(userId) {
  117. ret = append(ret, v)
  118. }
  119. }
  120. hm.lock.RUnlock()
  121. d, _ := json.Marshal(ret)
  122. return string(d)
  123. }
  124. func (hm *historyMgr) addHistory(h snghistory) {
  125. hm.lock.Lock()
  126. hm.histories = append(hm.histories, h)
  127. hm.isDirty = true
  128. hm.lock.Unlock()
  129. }