package gate import ( "bet24.com/log" "bet24.com/servers/common" "sync" "time" ) const ( max_record = 100 max_idle = 1800 // 半小时不发指令就删除 ) type messageData struct { data string t int64 } type userRecord struct { msgList []messageData ping int64 } func newUserRecord() *userRecord { ret := new(userRecord) return ret } func (ur *userRecord) addRecord(msg string) { count := len(ur.msgList) if count >= max_record { ur.msgList = ur.msgList[(count - max_record + 1):] } ur.msgList = append(ur.msgList, messageData{data: msg, t: time.Now().UnixNano() / 1000000}) ur.ping = time.Now().Unix() } func (ur *userRecord) isTimeout() bool { return time.Now().Unix()-ur.ping >= max_idle } type messageRecord struct { lock *sync.RWMutex userList map[int]*userRecord } func newMessageRecord() *messageRecord { ret := new(messageRecord) ret.lock = &sync.RWMutex{} ret.userList = make(map[int]*userRecord) ret.checkClear() return ret } func (mr *messageRecord) clear(userId int) { mr.lock.Lock() if userId <= 0 { mr.userList = make(map[int]*userRecord) } else { delete(mr.userList, userId) } mr.lock.Unlock() } func (mr *messageRecord) addRecord(userId int, msg string) { mr.lock.Lock() defer mr.lock.Unlock() userRecord, ok := mr.userList[userId] if !ok { userRecord = newUserRecord() mr.userList[userId] = userRecord } userRecord.addRecord(msg) } func (mr *messageRecord) dump(userId int) { mr.lock.RLock() ur, ok := mr.userList[userId] mr.lock.RUnlock() if !ok { log.Release("message record for userId[%d] not exist", userId) return } log.Release("message record for userId[%d] len = %d idle = %d", userId, len(ur.msgList), time.Now().Unix()-ur.ping) for _, v := range ur.msgList { log.Release(" [%s:%d] %s", common.TimeStampToString(v.t/1000), v.t%1000, v.data) } log.Release("-----------------------------") } func (mr *messageRecord) checkClear() { time.AfterFunc(600*time.Second, mr.checkClear) var toRemove []int mr.lock.RLock() for k, v := range mr.userList { if v.isTimeout() { toRemove = append(toRemove, k) } } mr.lock.RUnlock() if len(toRemove) == 0 { return } mr.lock.Lock() for _, v := range toRemove { delete(mr.userList, v) } mr.lock.Unlock() }