| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- package handler
- import (
- "bet24.com/log"
- "bet24.com/redis"
- pb "bet24.com/servers/micros/privateroom/proto"
- "encoding/json"
- "sort"
- "strconv"
- "sync"
- "time"
- )
- const max_history_sec = 86400 // 最多存储时长
- const refresh_config_sec = 600
- func getRedisKey() string {
- return "privateroom:history"
- }
- type historyItem struct {
- pb.RoomInfoBrief
- Owner int
- StartTime string
- RoomType string
- Winners []int
- HistoryTime int64
- EndType string
- }
- func (hi *historyItem) isUserRelated(userId int) bool {
- if hi.Owner == userId {
- return true
- }
- for _, v := range hi.UserList {
- if v == nil {
- continue
- }
- if v.UserId == userId {
- return true
- }
- }
- return false
- }
- func (h *historyItem) dump(detail bool) {
- log.Release(" RoomNo:%d Creator:%d GameId:%d Rule:%s EndType[%s]", h.RoomNo, h.Owner, h.GameId, h.RuleName, h.EndType)
- if !detail {
- return
- }
- for _, v := range h.UserList {
- if v == nil {
- continue
- }
- log.Release(" User[%d] Score[%d]", v.UserId, v.Score)
- }
- }
- type historyMgr struct {
- isDirty bool
- lock *sync.RWMutex
- histories []historyItem
- }
- var historymgr *historyMgr
- func getHistoryManager() *historyMgr {
- if historymgr == nil {
- historymgr = new(historyMgr)
- }
- return historymgr
- }
- func (m *historyMgr) run() {
- log.Release("privateroom.historymgr.run()")
- m.lock = &sync.RWMutex{}
- m.loadHistoryFromRedis()
- m.flush()
- }
- func (m *historyMgr) loadHistoryFromRedis() {
- data, ok := redis.String_Get(getRedisKey())
- if data == "" || !ok {
- return
- }
- m.lock.Lock()
- err := json.Unmarshal([]byte(data), &m.histories)
- m.lock.Unlock()
- if err != nil {
- log.Release("privateroom.historyMgr.loadHistoryFromRedis Unmarshal failed err:%v,%s", err, data)
- return
- }
- }
- func (m *historyMgr) addHistory(item roomInfo, endType string) {
- hi := historyItem{
- RoomInfoBrief: *item.ToBrief(),
- StartTime: item.StartTime,
- RoomType: item.RoomType,
- EndType: endType,
- HistoryTime: time.Now().Unix(),
- }
- if len(item.Winners) > 0 {
- hi.Winners = make([]int, len(item.Winners))
- copy(hi.Winners, item.Winners)
- }
- m.lock.Lock()
- m.isDirty = true
- m.histories = append(m.histories, hi)
- m.lock.Unlock()
- go writeRoomRecordToDB(&item)
- }
- func (m *historyMgr) checkTimeout() {
- now := time.Now().Unix()
- removeIndex := 0
- m.lock.RLock()
- for i := 0; i < len(m.histories); i++ {
- removeIndex = i
- if now-m.histories[i].HistoryTime < max_history_sec {
- break
- }
- }
- m.lock.RUnlock()
- if removeIndex == 0 {
- return
- }
- log.Release("privateroom.historymgr.checkTimeout removeIndex = %d", removeIndex)
- m.lock.Lock()
- m.isDirty = true
- m.histories = m.histories[removeIndex:]
- m.lock.Unlock()
- }
- func (m *historyMgr) forceFlush() {
- m.isDirty = true
- m.doFlush()
- }
- func (m *historyMgr) flush() {
- time.AfterFunc(refresh_config_sec*time.Second, m.flush)
- m.checkTimeout()
- if !m.isDirty {
- return
- }
- m.doFlush()
- }
- func (m *historyMgr) doFlush() {
- m.lock.RLock()
- m.isDirty = false
- d, _ := json.Marshal(m.histories)
- m.lock.RUnlock()
- go redis.String_Set(getRedisKey(), string(d))
- }
- func (m *historyMgr) dump(param string) {
- log.Release("-------------------------------")
- log.Release("historyMgr.historyMgr.dump %s", param)
- defer func() {
- log.Release("+++++++++++++++++++++++++++++++")
- log.Release("")
- }()
- if param == "" {
- m.lock.RLock()
- for _, v := range m.histories {
- v.dump(false)
- }
- m.lock.RUnlock()
- return
- }
- roomNo, err := strconv.Atoi(param)
- if err != nil {
- log.Release("invalid param %s", param)
- return
- }
- m.lock.RLock()
- for _, v := range m.histories {
- if v.RoomNo != roomNo {
- continue
- }
- v.dump(true)
- }
- m.lock.RUnlock()
- }
- func (m *historyMgr) getHistory(userId int) string {
- var ret []historyItem
- m.lock.RLock()
- for _, v := range m.histories {
- if v.isUserRelated(userId) {
- ret = append(ret, v)
- }
- }
- m.lock.RUnlock()
- sort.Slice(ret, func(i, j int) bool {
- return ret[i].HistoryTime > ret[j].HistoryTime
- })
- d, _ := json.Marshal(ret)
- return string(d)
- }
|