package hotime import ( . "code.hoteas.com/golang/hotime/cache" . "code.hoteas.com/golang/hotime/common" "sync" ) // session对象 type SessionIns struct { *HoTimeCache SessionId string Map ContextBase mutex sync.RWMutex } // set 保存 session 到缓存,必须在锁内调用或传入深拷贝的 map func (that *SessionIns) setWithCopy() { // 深拷贝 Map 防止并发修改 that.mutex.RLock() copyMap := make(Map, len(that.Map)) for k, v := range that.Map { copyMap[k] = v } that.mutex.RUnlock() that.HoTimeCache.Session(HEAD_SESSION_ADD+that.SessionId, copyMap) } func (that *SessionIns) Session(key string, data ...interface{}) *Obj { that.mutex.Lock() if that.Map == nil { that.getWithoutLock() } that.mutex.Unlock() if len(data) != 0 { that.mutex.Lock() if data[0] == nil { delete(that.Map, key) } else { that.Map[key] = data[0] } that.mutex.Unlock() // 使用深拷贝版本保存,避免并发问题 that.setWithCopy() return &Obj{Data: nil} } that.mutex.RLock() result := &Obj{Data: that.Map.Get(key)} that.mutex.RUnlock() return result } // getWithoutLock 内部使用,调用前需要已持有锁 func (that *SessionIns) getWithoutLock() { that.Map = that.HoTimeCache.Session(HEAD_SESSION_ADD + that.SessionId).ToMap() if that.Map != nil { return } that.Map = Map{} // 保存时也需要深拷贝 copyMap := make(Map, len(that.Map)) for k, v := range that.Map { copyMap[k] = v } that.HoTimeCache.Session(HEAD_SESSION_ADD+that.SessionId, copyMap) } func (that *SessionIns) get() { that.mutex.Lock() defer that.mutex.Unlock() that.getWithoutLock() } func (that *SessionIns) Init(cache *HoTimeCache) { that.mutex = sync.RWMutex{} that.HoTimeCache = cache }