123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- package httpsession
- import (
- "sync"
- "time"
- )
- var _ Store = NewMemoryStore(30)
- type sessionNode struct {
- lock sync.RWMutex
- kvs map[string]interface{}
- last time.Time
- maxAge time.Duration
- }
- func (node *sessionNode) Get(key string) interface{} {
- node.lock.RLock()
- v := node.kvs[key]
- node.lock.RUnlock()
- node.lock.Lock()
- node.last = time.Now()
- node.lock.Unlock()
- return v
- }
- func (node *sessionNode) GetMultiple() map[string]interface{} {
- m := make(map[string]interface{})
- node.lock.RLock()
- for k, v := range node.kvs {
- m[k] = v
- }
- node.lock.RUnlock()
- node.lock.Lock()
- node.last = time.Now()
- node.lock.Unlock()
- return m
- }
- func (node *sessionNode) Set(key string, v interface{}) {
- node.lock.Lock()
- node.kvs[key] = v
- node.last = time.Now()
- node.lock.Unlock()
- }
- func (node *sessionNode) SetMultiple(m map[string]interface{}) error {
- node.lock.Lock()
- for k, v := range m {
- node.kvs[k] = v
- }
- node.last = time.Now()
- node.lock.Unlock()
- return nil
- }
- func (node *sessionNode) Del(keys ...string) {
- node.lock.Lock()
- for _, v := range keys {
- delete(node.kvs, v)
- }
- node.last = time.Now()
- node.lock.Unlock()
- }
- //根据自定义字段,更新
- func (node *sessionNode) UpdateByCustomField(findkey string, findvalue interface{}, setkey string, setvalue interface{}) bool {
- node.lock.Lock()
- if v2, ok := node.kvs[findkey]; ok && v2 == findvalue {
- //存在
- if setkey != "" {
- flag := setkey[:1]
- switch flag {
- case "+":
- nkey := setkey[1:]
- node.kvs[nkey] = node.kvs[nkey].(int) + setvalue.(int)
- case "-":
- nkey := setkey[1:]
- node.kvs[nkey] = node.kvs[nkey].(int) - setvalue.(int)
- default:
- node.kvs[setkey] = setvalue
- }
- node.last = time.Now()
- } else {
- mapVal := setvalue.(*map[string]interface{})
- for k, v := range *mapVal {
- node.kvs[k] = v
- }
- node.last = time.Now()
- }
- }
- node.lock.Unlock()
- return true
- }
- type MemoryStore struct {
- lock sync.RWMutex
- nodes map[Id]*sessionNode
- GcInterval time.Duration
- maxAge time.Duration
- }
- func NewMemoryStore(maxAge time.Duration) *MemoryStore {
- return &MemoryStore{nodes: make(map[Id]*sessionNode),
- maxAge: maxAge, GcInterval: 10 * time.Second}
- }
- func (store *MemoryStore) SetMaxAge(maxAge time.Duration) {
- store.lock.Lock()
- store.maxAge = maxAge
- store.lock.Unlock()
- }
- func (store *MemoryStore) Get(id Id, key string) interface{} {
- store.lock.RLock()
- node, ok := store.nodes[id]
- store.lock.RUnlock()
- if !ok {
- return nil
- }
- if store.maxAge > 0 && time.Now().Sub(node.last) > node.maxAge {
- // lazy DELETE expire
- store.lock.Lock()
- delete(store.nodes, id)
- store.lock.Unlock()
- return nil
- }
- return node.Get(key)
- }
- func (store *MemoryStore) GetMultiple(id Id) map[string]interface{} {
- store.lock.RLock()
- node, ok := store.nodes[id]
- store.lock.RUnlock()
- if !ok {
- return make(map[string]interface{})
- }
- if store.maxAge > 0 && time.Now().Sub(node.last) > node.maxAge {
- // lazy DELETE expire
- store.lock.Lock()
- delete(store.nodes, id)
- store.lock.Unlock()
- return make(map[string]interface{})
- }
- return node.GetMultiple()
- }
- func (store *MemoryStore) Set(id Id, key string, value interface{}) {
- store.lock.RLock()
- node, ok := store.nodes[id]
- store.lock.RUnlock()
- if !ok {
- store.lock.Lock()
- node = store.newNode()
- node.kvs[key] = value
- store.nodes[id] = node
- store.lock.Unlock()
- }
- node.Set(key, value)
- }
- func (store *MemoryStore) SetMultiple(id Id, m map[string]interface{}) error {
- store.lock.RLock()
- node, ok := store.nodes[id]
- store.lock.RUnlock()
- if !ok {
- store.lock.Lock()
- node = store.newNode()
- for k, v := range m {
- node.kvs[k] = v
- }
- store.nodes[id] = node
- store.lock.Unlock()
- }
- return node.SetMultiple(m)
- }
- func (store *MemoryStore) newNode() *sessionNode {
- return &sessionNode{
- kvs: make(map[string]interface{}),
- last: time.Now(),
- maxAge: store.maxAge,
- }
- }
- func (store *MemoryStore) Add(id Id) {
- node := store.newNode()
- store.lock.Lock()
- store.nodes[id] = node
- store.lock.Unlock()
- }
- func (store *MemoryStore) Del(id Id, keys ...string) bool {
- store.lock.RLock()
- node, ok := store.nodes[id]
- store.lock.RUnlock()
- if ok {
- node.Del(keys...)
- }
- return true
- }
- func (store *MemoryStore) Exist(id Id) bool {
- store.lock.RLock()
- defer store.lock.RUnlock()
- _, ok := store.nodes[id]
- return ok
- }
- func (store *MemoryStore) Clear(id Id) bool {
- store.lock.Lock()
- defer store.lock.Unlock()
- delete(store.nodes, id)
- return true
- }
- func (store *MemoryStore) Run() error {
- time.AfterFunc(store.GcInterval, func() {
- store.Run()
- store.GC()
- })
- return nil
- }
- //根据指定字段更新Session
- func (store *MemoryStore) UpdateByCustomField(findkey string, findvalue interface{}, setkey string, setvalue interface{}) bool {
- store.lock.RLock()
- for _, v := range store.nodes {
- v.UpdateByCustomField(findkey, findvalue, setkey, setvalue)
- }
- store.lock.RUnlock()
- return true
- }
- //
- func (store *MemoryStore) GC() {
- store.lock.Lock()
- defer store.lock.Unlock()
- if store.maxAge == 0 {
- return
- }
- var i, j int
- for k, v := range store.nodes {
- if j > 20 || i > 5 {
- break
- }
- if time.Now().Sub(v.last) > v.maxAge {
- delete(store.nodes, k)
- i = i + 1
- }
- j = j + 1
- }
- }
|