redis_cluster.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. // Package redis for session provider
  15. //
  16. // depend on github.com/go-redis/redis
  17. //
  18. // go install github.com/go-redis/redis
  19. //
  20. // Usage:
  21. // import(
  22. // _ "github.com/cnlh/nps/vender/github.com/astaxie/beego/session/redis_cluster"
  23. // "github.com/cnlh/nps/vender/github.com/astaxie/beego/session"
  24. // )
  25. //
  26. // func init() {
  27. // globalSessions, _ = session.NewManager("redis_cluster", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:7070;127.0.0.1:7071"}``)
  28. // go globalSessions.GC()
  29. // }
  30. //
  31. // more docs: http://beego.me/docs/module/session.md
  32. package redis_cluster
  33. import (
  34. "github.com/cnlh/nps/vender/github.com/astaxie/beego/session"
  35. rediss "github.com/go-redis/redis"
  36. "net/http"
  37. "strconv"
  38. "strings"
  39. "sync"
  40. "time"
  41. )
  42. var redispder = &Provider{}
  43. // MaxPoolSize redis_cluster max pool size
  44. var MaxPoolSize = 1000
  45. // SessionStore redis_cluster session store
  46. type SessionStore struct {
  47. p *rediss.ClusterClient
  48. sid string
  49. lock sync.RWMutex
  50. values map[interface{}]interface{}
  51. maxlifetime int64
  52. }
  53. // Set value in redis_cluster session
  54. func (rs *SessionStore) Set(key, value interface{}) error {
  55. rs.lock.Lock()
  56. defer rs.lock.Unlock()
  57. rs.values[key] = value
  58. return nil
  59. }
  60. // Get value in redis_cluster session
  61. func (rs *SessionStore) Get(key interface{}) interface{} {
  62. rs.lock.RLock()
  63. defer rs.lock.RUnlock()
  64. if v, ok := rs.values[key]; ok {
  65. return v
  66. }
  67. return nil
  68. }
  69. // Delete value in redis_cluster session
  70. func (rs *SessionStore) Delete(key interface{}) error {
  71. rs.lock.Lock()
  72. defer rs.lock.Unlock()
  73. delete(rs.values, key)
  74. return nil
  75. }
  76. // Flush clear all values in redis_cluster session
  77. func (rs *SessionStore) Flush() error {
  78. rs.lock.Lock()
  79. defer rs.lock.Unlock()
  80. rs.values = make(map[interface{}]interface{})
  81. return nil
  82. }
  83. // SessionID get redis_cluster session id
  84. func (rs *SessionStore) SessionID() string {
  85. return rs.sid
  86. }
  87. // SessionRelease save session values to redis_cluster
  88. func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
  89. b, err := session.EncodeGob(rs.values)
  90. if err != nil {
  91. return
  92. }
  93. c := rs.p
  94. c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second)
  95. }
  96. // Provider redis_cluster session provider
  97. type Provider struct {
  98. maxlifetime int64
  99. savePath string
  100. poolsize int
  101. password string
  102. dbNum int
  103. poollist *rediss.ClusterClient
  104. }
  105. // SessionInit init redis_cluster session
  106. // savepath like redis server addr,pool size,password,dbnum
  107. // e.g. 127.0.0.1:6379;127.0.0.1:6380,100,test,0
  108. func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error {
  109. rp.maxlifetime = maxlifetime
  110. configs := strings.Split(savePath, ",")
  111. if len(configs) > 0 {
  112. rp.savePath = configs[0]
  113. }
  114. if len(configs) > 1 {
  115. poolsize, err := strconv.Atoi(configs[1])
  116. if err != nil || poolsize < 0 {
  117. rp.poolsize = MaxPoolSize
  118. } else {
  119. rp.poolsize = poolsize
  120. }
  121. } else {
  122. rp.poolsize = MaxPoolSize
  123. }
  124. if len(configs) > 2 {
  125. rp.password = configs[2]
  126. }
  127. if len(configs) > 3 {
  128. dbnum, err := strconv.Atoi(configs[3])
  129. if err != nil || dbnum < 0 {
  130. rp.dbNum = 0
  131. } else {
  132. rp.dbNum = dbnum
  133. }
  134. } else {
  135. rp.dbNum = 0
  136. }
  137. rp.poollist = rediss.NewClusterClient(&rediss.ClusterOptions{
  138. Addrs: strings.Split(rp.savePath, ";"),
  139. Password: rp.password,
  140. PoolSize: rp.poolsize,
  141. })
  142. return rp.poollist.Ping().Err()
  143. }
  144. // SessionRead read redis_cluster session by sid
  145. func (rp *Provider) SessionRead(sid string) (session.Store, error) {
  146. var kv map[interface{}]interface{}
  147. kvs, err := rp.poollist.Get(sid).Result()
  148. if err != nil && err != rediss.Nil {
  149. return nil, err
  150. }
  151. if len(kvs) == 0 {
  152. kv = make(map[interface{}]interface{})
  153. } else {
  154. if kv, err = session.DecodeGob([]byte(kvs)); err != nil {
  155. return nil, err
  156. }
  157. }
  158. rs := &SessionStore{p: rp.poollist, sid: sid, values: kv, maxlifetime: rp.maxlifetime}
  159. return rs, nil
  160. }
  161. // SessionExist check redis_cluster session exist by sid
  162. func (rp *Provider) SessionExist(sid string) bool {
  163. c := rp.poollist
  164. if existed, err := c.Exists(sid).Result(); err != nil || existed == 0 {
  165. return false
  166. }
  167. return true
  168. }
  169. // SessionRegenerate generate new sid for redis_cluster session
  170. func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
  171. c := rp.poollist
  172. if existed, err := c.Exists(oldsid).Result(); err != nil || existed == 0 {
  173. // oldsid doesn't exists, set the new sid directly
  174. // ignore error here, since if it return error
  175. // the existed value will be 0
  176. c.Set(sid, "", time.Duration(rp.maxlifetime)*time.Second)
  177. } else {
  178. c.Rename(oldsid, sid)
  179. c.Expire(sid, time.Duration(rp.maxlifetime)*time.Second)
  180. }
  181. return rp.SessionRead(sid)
  182. }
  183. // SessionDestroy delete redis session by id
  184. func (rp *Provider) SessionDestroy(sid string) error {
  185. c := rp.poollist
  186. c.Del(sid)
  187. return nil
  188. }
  189. // SessionGC Impelment method, no used.
  190. func (rp *Provider) SessionGC() {
  191. }
  192. // SessionAll return all activeSession
  193. func (rp *Provider) SessionAll() int {
  194. return 0
  195. }
  196. func init() {
  197. session.Register("redis_cluster", redispder)
  198. }