Files
hotime/session.go
T

160 lines
3.3 KiB
Go
Raw Permalink Normal View History

2017-08-04 08:20:59 +00:00
package hotime
2021-05-24 07:27:41 +08:00
import (
"sync"
2022-03-13 01:12:29 +08:00
. "code.hoteas.com/golang/hotime/cache"
. "code.hoteas.com/golang/hotime/common"
2021-05-24 07:27:41 +08:00
)
// session对象
2017-08-04 08:20:59 +00:00
type SessionIns struct {
*HoTimeCache
SessionId string
2017-08-04 08:20:59 +00:00
Map
2021-05-24 07:27:41 +08:00
ContextBase
mutex sync.RWMutex
2017-08-04 08:20:59 +00:00
}
// 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)
2017-08-04 08:20:59 +00:00
}
2021-05-25 05:08:17 +08:00
func (that *SessionIns) Session(key string, data ...interface{}) *Obj {
that.mutex.Lock()
2021-05-25 05:08:17 +08:00
if that.Map == nil {
that.getWithoutLock()
2017-08-04 08:20:59 +00:00
}
that.mutex.Unlock()
2017-08-04 08:20:59 +00:00
2017-08-10 10:14:56 +00:00
if len(data) != 0 {
that.mutex.Lock()
2017-08-10 10:14:56 +00:00
if data[0] == nil {
2021-05-25 05:08:17 +08:00
delete(that.Map, key)
2017-08-10 10:14:56 +00:00
} else {
2021-05-25 05:08:17 +08:00
that.Map[key] = data[0]
2017-08-04 08:20:59 +00:00
}
that.mutex.Unlock()
// 使用深拷贝版本保存,避免并发问题
that.setWithCopy()
2017-08-10 10:14:56 +00:00
return &Obj{Data: nil}
2017-08-04 08:20:59 +00:00
}
that.mutex.RLock()
result := &Obj{Data: that.Map.Get(key)}
that.mutex.RUnlock()
return result
2017-08-04 08:20:59 +00:00
}
// SessionsSet 批量设置session字段,只触发一次数据库写入
// 用法:that.SessionsSet(Map{"key1": value1, "key2": value2, ...})
// 性能优化:设置N个字段只触发1次数据库写入(而非N次)
func (that *SessionIns) SessionsSet(data Map) {
if len(data) == 0 {
return
}
that.mutex.Lock()
if that.Map == nil {
that.getWithoutLock()
}
// 批量设置所有字段
for key, value := range data {
if value == nil {
delete(that.Map, key)
} else {
that.Map[key] = value
}
}
that.mutex.Unlock()
// 只触发一次数据库写入
that.setWithCopy()
}
// SessionsDelete 批量删除session字段,只触发一次数据库写入
// 用法:that.SessionsDelete("key1", "key2", ...)
func (that *SessionIns) SessionsDelete(keys ...string) {
if len(keys) == 0 {
return
}
that.mutex.Lock()
if that.Map == nil {
that.getWithoutLock()
}
// 批量删除所有字段
for _, key := range keys {
delete(that.Map, key)
}
that.mutex.Unlock()
// 只触发一次数据库写入
that.setWithCopy()
}
// SessionsGet 批量获取session字段
// 用法:result := that.SessionsGet("key1", "key2", ...)
// 返回 Mapkey 为字段名,value 为字段值(不存在的 key 不包含在结果中)
func (that *SessionIns) SessionsGet(keys ...string) Map {
if len(keys) == 0 {
return Map{}
}
that.mutex.Lock()
if that.Map == nil {
that.getWithoutLock()
}
that.mutex.Unlock()
result := make(Map, len(keys))
that.mutex.RLock()
for _, key := range keys {
if value, exists := that.Map[key]; exists {
result[key] = value
}
}
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
2017-08-04 08:20:59 +00:00
}
2021-05-25 05:08:17 +08:00
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)
}
2017-08-04 08:20:59 +00:00
func (that *SessionIns) get() {
that.mutex.Lock()
defer that.mutex.Unlock()
that.getWithoutLock()
2017-08-04 08:20:59 +00:00
}
func (that *SessionIns) Init(cache *HoTimeCache) {
that.mutex = sync.RWMutex{}
that.HoTimeCache = cache
2017-08-10 10:14:56 +00:00
}