memorystore.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. package httpsession
  2. import (
  3. "sync"
  4. "time"
  5. )
  6. var _ Store = NewMemoryStore(30)
  7. type sessionNode struct {
  8. lock sync.RWMutex
  9. kvs map[string]interface{}
  10. last time.Time
  11. maxAge time.Duration
  12. }
  13. func (node *sessionNode) Get(key string) interface{} {
  14. node.lock.RLock()
  15. v := node.kvs[key]
  16. node.lock.RUnlock()
  17. node.lock.Lock()
  18. node.last = time.Now()
  19. node.lock.Unlock()
  20. return v
  21. }
  22. func (node *sessionNode) GetMultiple() map[string]interface{} {
  23. m := make(map[string]interface{})
  24. node.lock.RLock()
  25. for k, v := range node.kvs {
  26. m[k] = v
  27. }
  28. node.lock.RUnlock()
  29. node.lock.Lock()
  30. node.last = time.Now()
  31. node.lock.Unlock()
  32. return m
  33. }
  34. func (node *sessionNode) Set(key string, v interface{}) {
  35. node.lock.Lock()
  36. node.kvs[key] = v
  37. node.last = time.Now()
  38. node.lock.Unlock()
  39. }
  40. func (node *sessionNode) SetMultiple(m map[string]interface{}) error {
  41. node.lock.Lock()
  42. for k, v := range m {
  43. node.kvs[k] = v
  44. }
  45. node.last = time.Now()
  46. node.lock.Unlock()
  47. return nil
  48. }
  49. func (node *sessionNode) Del(keys ...string) {
  50. node.lock.Lock()
  51. for _, v := range keys {
  52. delete(node.kvs, v)
  53. }
  54. node.last = time.Now()
  55. node.lock.Unlock()
  56. }
  57. //根据自定义字段,更新
  58. func (node *sessionNode) UpdateByCustomField(findkey string, findvalue interface{}, setkey string, setvalue interface{}) bool {
  59. node.lock.Lock()
  60. if v2, ok := node.kvs[findkey]; ok && v2 == findvalue {
  61. //存在
  62. if setkey != "" {
  63. flag := setkey[:1]
  64. switch flag {
  65. case "+":
  66. nkey := setkey[1:]
  67. node.kvs[nkey] = node.kvs[nkey].(int) + setvalue.(int)
  68. case "-":
  69. nkey := setkey[1:]
  70. node.kvs[nkey] = node.kvs[nkey].(int) - setvalue.(int)
  71. default:
  72. node.kvs[setkey] = setvalue
  73. }
  74. node.last = time.Now()
  75. } else {
  76. mapVal := setvalue.(*map[string]interface{})
  77. for k, v := range *mapVal {
  78. node.kvs[k] = v
  79. }
  80. node.last = time.Now()
  81. }
  82. }
  83. node.lock.Unlock()
  84. return true
  85. }
  86. type MemoryStore struct {
  87. lock sync.RWMutex
  88. nodes map[Id]*sessionNode
  89. GcInterval time.Duration
  90. maxAge time.Duration
  91. }
  92. func NewMemoryStore(maxAge time.Duration) *MemoryStore {
  93. return &MemoryStore{nodes: make(map[Id]*sessionNode),
  94. maxAge: maxAge, GcInterval: 10 * time.Second}
  95. }
  96. func (store *MemoryStore) SetMaxAge(maxAge time.Duration) {
  97. store.lock.Lock()
  98. store.maxAge = maxAge
  99. store.lock.Unlock()
  100. }
  101. func (store *MemoryStore) Get(id Id, key string) interface{} {
  102. store.lock.RLock()
  103. node, ok := store.nodes[id]
  104. store.lock.RUnlock()
  105. if !ok {
  106. return nil
  107. }
  108. if store.maxAge > 0 && time.Now().Sub(node.last) > node.maxAge {
  109. // lazy DELETE expire
  110. store.lock.Lock()
  111. delete(store.nodes, id)
  112. store.lock.Unlock()
  113. return nil
  114. }
  115. return node.Get(key)
  116. }
  117. func (store *MemoryStore) GetMultiple(id Id) map[string]interface{} {
  118. store.lock.RLock()
  119. node, ok := store.nodes[id]
  120. store.lock.RUnlock()
  121. if !ok {
  122. return make(map[string]interface{})
  123. }
  124. if store.maxAge > 0 && time.Now().Sub(node.last) > node.maxAge {
  125. // lazy DELETE expire
  126. store.lock.Lock()
  127. delete(store.nodes, id)
  128. store.lock.Unlock()
  129. return make(map[string]interface{})
  130. }
  131. return node.GetMultiple()
  132. }
  133. func (store *MemoryStore) Set(id Id, key string, value interface{}) {
  134. store.lock.RLock()
  135. node, ok := store.nodes[id]
  136. store.lock.RUnlock()
  137. if !ok {
  138. store.lock.Lock()
  139. node = store.newNode()
  140. node.kvs[key] = value
  141. store.nodes[id] = node
  142. store.lock.Unlock()
  143. }
  144. node.Set(key, value)
  145. }
  146. func (store *MemoryStore) SetMultiple(id Id, m map[string]interface{}) error {
  147. store.lock.RLock()
  148. node, ok := store.nodes[id]
  149. store.lock.RUnlock()
  150. if !ok {
  151. store.lock.Lock()
  152. node = store.newNode()
  153. for k, v := range m {
  154. node.kvs[k] = v
  155. }
  156. store.nodes[id] = node
  157. store.lock.Unlock()
  158. }
  159. return node.SetMultiple(m)
  160. }
  161. func (store *MemoryStore) newNode() *sessionNode {
  162. return &sessionNode{
  163. kvs: make(map[string]interface{}),
  164. last: time.Now(),
  165. maxAge: store.maxAge,
  166. }
  167. }
  168. func (store *MemoryStore) Add(id Id) {
  169. node := store.newNode()
  170. store.lock.Lock()
  171. store.nodes[id] = node
  172. store.lock.Unlock()
  173. }
  174. func (store *MemoryStore) Del(id Id, keys ...string) bool {
  175. store.lock.RLock()
  176. node, ok := store.nodes[id]
  177. store.lock.RUnlock()
  178. if ok {
  179. node.Del(keys...)
  180. }
  181. return true
  182. }
  183. func (store *MemoryStore) Exist(id Id) bool {
  184. store.lock.RLock()
  185. defer store.lock.RUnlock()
  186. _, ok := store.nodes[id]
  187. return ok
  188. }
  189. func (store *MemoryStore) Clear(id Id) bool {
  190. store.lock.Lock()
  191. defer store.lock.Unlock()
  192. delete(store.nodes, id)
  193. return true
  194. }
  195. func (store *MemoryStore) Run() error {
  196. time.AfterFunc(store.GcInterval, func() {
  197. store.Run()
  198. store.GC()
  199. })
  200. return nil
  201. }
  202. //根据指定字段更新Session
  203. func (store *MemoryStore) UpdateByCustomField(findkey string, findvalue interface{}, setkey string, setvalue interface{}) bool {
  204. store.lock.RLock()
  205. for _, v := range store.nodes {
  206. v.UpdateByCustomField(findkey, findvalue, setkey, setvalue)
  207. }
  208. store.lock.RUnlock()
  209. return true
  210. }
  211. //
  212. func (store *MemoryStore) GC() {
  213. store.lock.Lock()
  214. defer store.lock.Unlock()
  215. if store.maxAge == 0 {
  216. return
  217. }
  218. var i, j int
  219. for k, v := range store.nodes {
  220. if j > 20 || i > 5 {
  221. break
  222. }
  223. if time.Now().Sub(v.last) > v.maxAge {
  224. delete(store.nodes, k)
  225. i = i + 1
  226. }
  227. j = j + 1
  228. }
  229. }