github.com/astaxie/beego@v1.12.3/session/sess_mem.go (about) 1 // Copyright 2014 beego Author. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package session 16 17 import ( 18 "container/list" 19 "net/http" 20 "sync" 21 "time" 22 ) 23 24 var mempder = &MemProvider{list: list.New(), sessions: make(map[string]*list.Element)} 25 26 // MemSessionStore memory session store. 27 // it saved sessions in a map in memory. 28 type MemSessionStore struct { 29 sid string //session id 30 timeAccessed time.Time //last access time 31 value map[interface{}]interface{} //session store 32 lock sync.RWMutex 33 } 34 35 // Set value to memory session 36 func (st *MemSessionStore) Set(key, value interface{}) error { 37 st.lock.Lock() 38 defer st.lock.Unlock() 39 st.value[key] = value 40 return nil 41 } 42 43 // Get value from memory session by key 44 func (st *MemSessionStore) Get(key interface{}) interface{} { 45 st.lock.RLock() 46 defer st.lock.RUnlock() 47 if v, ok := st.value[key]; ok { 48 return v 49 } 50 return nil 51 } 52 53 // Delete in memory session by key 54 func (st *MemSessionStore) Delete(key interface{}) error { 55 st.lock.Lock() 56 defer st.lock.Unlock() 57 delete(st.value, key) 58 return nil 59 } 60 61 // Flush clear all values in memory session 62 func (st *MemSessionStore) Flush() error { 63 st.lock.Lock() 64 defer st.lock.Unlock() 65 st.value = make(map[interface{}]interface{}) 66 return nil 67 } 68 69 // SessionID get this id of memory session store 70 func (st *MemSessionStore) SessionID() string { 71 return st.sid 72 } 73 74 // SessionRelease Implement method, no used. 75 func (st *MemSessionStore) SessionRelease(w http.ResponseWriter) { 76 } 77 78 // MemProvider Implement the provider interface 79 type MemProvider struct { 80 lock sync.RWMutex // locker 81 sessions map[string]*list.Element // map in memory 82 list *list.List // for gc 83 maxlifetime int64 84 savePath string 85 } 86 87 // SessionInit init memory session 88 func (pder *MemProvider) SessionInit(maxlifetime int64, savePath string) error { 89 pder.maxlifetime = maxlifetime 90 pder.savePath = savePath 91 return nil 92 } 93 94 // SessionRead get memory session store by sid 95 func (pder *MemProvider) SessionRead(sid string) (Store, error) { 96 pder.lock.RLock() 97 if element, ok := pder.sessions[sid]; ok { 98 go pder.SessionUpdate(sid) 99 pder.lock.RUnlock() 100 return element.Value.(*MemSessionStore), nil 101 } 102 pder.lock.RUnlock() 103 pder.lock.Lock() 104 newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})} 105 element := pder.list.PushFront(newsess) 106 pder.sessions[sid] = element 107 pder.lock.Unlock() 108 return newsess, nil 109 } 110 111 // SessionExist check session store exist in memory session by sid 112 func (pder *MemProvider) SessionExist(sid string) bool { 113 pder.lock.RLock() 114 defer pder.lock.RUnlock() 115 if _, ok := pder.sessions[sid]; ok { 116 return true 117 } 118 return false 119 } 120 121 // SessionRegenerate generate new sid for session store in memory session 122 func (pder *MemProvider) SessionRegenerate(oldsid, sid string) (Store, error) { 123 pder.lock.RLock() 124 if element, ok := pder.sessions[oldsid]; ok { 125 go pder.SessionUpdate(oldsid) 126 pder.lock.RUnlock() 127 pder.lock.Lock() 128 element.Value.(*MemSessionStore).sid = sid 129 pder.sessions[sid] = element 130 delete(pder.sessions, oldsid) 131 pder.lock.Unlock() 132 return element.Value.(*MemSessionStore), nil 133 } 134 pder.lock.RUnlock() 135 pder.lock.Lock() 136 newsess := &MemSessionStore{sid: sid, timeAccessed: time.Now(), value: make(map[interface{}]interface{})} 137 element := pder.list.PushFront(newsess) 138 pder.sessions[sid] = element 139 pder.lock.Unlock() 140 return newsess, nil 141 } 142 143 // SessionDestroy delete session store in memory session by id 144 func (pder *MemProvider) SessionDestroy(sid string) error { 145 pder.lock.Lock() 146 defer pder.lock.Unlock() 147 if element, ok := pder.sessions[sid]; ok { 148 delete(pder.sessions, sid) 149 pder.list.Remove(element) 150 return nil 151 } 152 return nil 153 } 154 155 // SessionGC clean expired session stores in memory session 156 func (pder *MemProvider) SessionGC() { 157 pder.lock.RLock() 158 for { 159 element := pder.list.Back() 160 if element == nil { 161 break 162 } 163 if (element.Value.(*MemSessionStore).timeAccessed.Unix() + pder.maxlifetime) < time.Now().Unix() { 164 pder.lock.RUnlock() 165 pder.lock.Lock() 166 pder.list.Remove(element) 167 delete(pder.sessions, element.Value.(*MemSessionStore).sid) 168 pder.lock.Unlock() 169 pder.lock.RLock() 170 } else { 171 break 172 } 173 } 174 pder.lock.RUnlock() 175 } 176 177 // SessionAll get count number of memory session 178 func (pder *MemProvider) SessionAll() int { 179 return pder.list.Len() 180 } 181 182 // SessionUpdate expand time of session store by id in memory session 183 func (pder *MemProvider) SessionUpdate(sid string) error { 184 pder.lock.Lock() 185 defer pder.lock.Unlock() 186 if element, ok := pder.sessions[sid]; ok { 187 element.Value.(*MemSessionStore).timeAccessed = time.Now() 188 pder.list.MoveToFront(element) 189 return nil 190 } 191 return nil 192 } 193 194 func init() { 195 Register("memory", mempder) 196 }