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