2773fda8 by astaxie

session:change the driver from beego to bradfitz

1 parent 99c03a2b
...@@ -11,18 +11,19 @@ package session ...@@ -11,18 +11,19 @@ package session
11 11
12 import ( 12 import (
13 "net/http" 13 "net/http"
14 "strings"
14 "sync" 15 "sync"
15 16
16 "github.com/astaxie/beego/session" 17 "github.com/astaxie/beego/session"
17 18
18 "github.com/beego/memcache" 19 "github.com/bradfitz/gomemcache/memcache"
19 ) 20 )
20 21
21 var mempder = &MemProvider{} 22 var mempder = &MemProvider{}
23 var client *memcache.Client
22 24
23 // memcache session store 25 // memcache session store
24 type MemcacheSessionStore struct { 26 type MemcacheSessionStore struct {
25 c *memcache.Connection
26 sid string 27 sid string
27 lock sync.RWMutex 28 lock sync.RWMutex
28 values map[interface{}]interface{} 29 values map[interface{}]interface{}
...@@ -71,19 +72,18 @@ func (rs *MemcacheSessionStore) SessionID() string { ...@@ -71,19 +72,18 @@ func (rs *MemcacheSessionStore) SessionID() string {
71 72
72 // save session values to redis 73 // save session values to redis
73 func (rs *MemcacheSessionStore) SessionRelease(w http.ResponseWriter) { 74 func (rs *MemcacheSessionStore) SessionRelease(w http.ResponseWriter) {
74 defer rs.c.Close()
75
76 b, err := session.EncodeGob(rs.values) 75 b, err := session.EncodeGob(rs.values)
77 if err != nil { 76 if err != nil {
78 return 77 return
79 } 78 }
80 rs.c.Set(rs.sid, 0, uint64(rs.maxlifetime), b) 79 item := memcache.Item{Key: rs.sid, Value: b, Expiration: int32(rs.maxlifetime)}
80 client.Set(&item)
81 } 81 }
82 82
83 // redis session provider 83 // redis session provider
84 type MemProvider struct { 84 type MemProvider struct {
85 maxlifetime int64 85 maxlifetime int64
86 savePath string 86 conninfo []string
87 poolsize int 87 poolsize int
88 password string 88 password string
89 } 89 }
...@@ -93,46 +93,44 @@ type MemProvider struct { ...@@ -93,46 +93,44 @@ type MemProvider struct {
93 // e.g. 127.0.0.1:9090 93 // e.g. 127.0.0.1:9090
94 func (rp *MemProvider) SessionInit(maxlifetime int64, savePath string) error { 94 func (rp *MemProvider) SessionInit(maxlifetime int64, savePath string) error {
95 rp.maxlifetime = maxlifetime 95 rp.maxlifetime = maxlifetime
96 rp.savePath = savePath 96 rp.conninfo = strings.Split(savePath, ";")
97 client = memcache.New(rp.conninfo...)
97 return nil 98 return nil
98 } 99 }
99 100
100 // read redis session by sid 101 // read redis session by sid
101 func (rp *MemProvider) SessionRead(sid string) (session.SessionStore, error) { 102 func (rp *MemProvider) SessionRead(sid string) (session.SessionStore, error) {
102 conn, err := rp.connectInit() 103 if client == nil {
103 if err != nil { 104 if err := rp.connectInit(); err != nil {
104 return nil, err 105 return nil, err
105 } 106 }
106 kvs, err := conn.Get(sid) 107 }
108 item, err := client.Get(sid)
107 if err != nil { 109 if err != nil {
108 return nil, err 110 return nil, err
109 } 111 }
110 var contain []byte
111 if len(kvs) > 0 {
112 contain = kvs[0].Value
113 }
114 var kv map[interface{}]interface{} 112 var kv map[interface{}]interface{}
115 if len(contain) == 0 { 113 if len(item.Value) == 0 {
116 kv = make(map[interface{}]interface{}) 114 kv = make(map[interface{}]interface{})
117 } else { 115 } else {
118 kv, err = session.DecodeGob(contain) 116 kv, err = session.DecodeGob(item.Value)
119 if err != nil { 117 if err != nil {
120 return nil, err 118 return nil, err
121 } 119 }
122 } 120 }
123 121
124 rs := &MemcacheSessionStore{c: conn, sid: sid, values: kv, maxlifetime: rp.maxlifetime} 122 rs := &MemcacheSessionStore{sid: sid, values: kv, maxlifetime: rp.maxlifetime}
125 return rs, nil 123 return rs, nil
126 } 124 }
127 125
128 // check redis session exist by sid 126 // check redis session exist by sid
129 func (rp *MemProvider) SessionExist(sid string) bool { 127 func (rp *MemProvider) SessionExist(sid string) bool {
130 conn, err := rp.connectInit() 128 if client == nil {
131 if err != nil { 129 if err := rp.connectInit(); err != nil {
132 return false 130 return false
133 } 131 }
134 defer conn.Close() 132 }
135 if kvs, err := conn.Get(sid); err != nil || len(kvs) == 0 { 133 if item, err := client.Get(sid); err != nil || len(item.Value) == 0 {
136 return false 134 return false
137 } else { 135 } else {
138 return true 136 return true
...@@ -141,51 +139,64 @@ func (rp *MemProvider) SessionExist(sid string) bool { ...@@ -141,51 +139,64 @@ func (rp *MemProvider) SessionExist(sid string) bool {
141 139
142 // generate new sid for redis session 140 // generate new sid for redis session
143 func (rp *MemProvider) SessionRegenerate(oldsid, sid string) (session.SessionStore, error) { 141 func (rp *MemProvider) SessionRegenerate(oldsid, sid string) (session.SessionStore, error) {
144 conn, err := rp.connectInit() 142 if client == nil {
145 if err != nil { 143 if err := rp.connectInit(); err != nil {
146 return nil, err 144 return nil, err
147 } 145 }
146 }
148 var contain []byte 147 var contain []byte
149 if kvs, err := conn.Get(sid); err != nil || len(kvs) == 0 { 148 if item, err := client.Get(sid); err != nil || len(item.Value) == 0 {
150 // oldsid doesn't exists, set the new sid directly 149 // oldsid doesn't exists, set the new sid directly
151 // ignore error here, since if it return error 150 // ignore error here, since if it return error
152 // the existed value will be 0 151 // the existed value will be 0
153 conn.Set(sid, 0, uint64(rp.maxlifetime), []byte("")) 152 item.Key = sid
153 item.Value = []byte("")
154 item.Expiration = int32(rp.maxlifetime)
155 client.Set(item)
154 } else { 156 } else {
155 conn.Delete(oldsid) 157 client.Delete(oldsid)
156 conn.Set(sid, 0, uint64(rp.maxlifetime), kvs[0].Value) 158 item.Key = sid
157 contain = kvs[0].Value 159 item.Value = item.Value
160 item.Expiration = int32(rp.maxlifetime)
161 client.Set(item)
162 contain = item.Value
158 } 163 }
159 164
160 var kv map[interface{}]interface{} 165 var kv map[interface{}]interface{}
161 if len(contain) == 0 { 166 if len(contain) == 0 {
162 kv = make(map[interface{}]interface{}) 167 kv = make(map[interface{}]interface{})
163 } else { 168 } else {
169 var err error
164 kv, err = session.DecodeGob(contain) 170 kv, err = session.DecodeGob(contain)
165 if err != nil { 171 if err != nil {
166 return nil, err 172 return nil, err
167 } 173 }
168 } 174 }
169 175
170 rs := &MemcacheSessionStore{c: conn, sid: sid, values: kv, maxlifetime: rp.maxlifetime} 176 rs := &MemcacheSessionStore{sid: sid, values: kv, maxlifetime: rp.maxlifetime}
171 return rs, nil 177 return rs, nil
172 } 178 }
173 179
174 // delete redis session by id 180 // delete redis session by id
175 func (rp *MemProvider) SessionDestroy(sid string) error { 181 func (rp *MemProvider) SessionDestroy(sid string) error {
176 conn, err := rp.connectInit() 182 if client == nil {
177 if err != nil { 183 if err := rp.connectInit(); err != nil {
178 return err 184 return err
179 } 185 }
180 defer conn.Close() 186 }
181 187
182 _, err = conn.Delete(sid) 188 err := client.Delete(sid)
183 if err != nil { 189 if err != nil {
184 return err 190 return err
185 } 191 }
186 return nil 192 return nil
187 } 193 }
188 194
195 func (rp *MemProvider) connectInit() error {
196 client = memcache.New(rp.conninfo...)
197 return nil
198 }
199
189 // Impelment method, no used. 200 // Impelment method, no used.
190 func (rp *MemProvider) SessionGC() { 201 func (rp *MemProvider) SessionGC() {
191 return 202 return
...@@ -196,15 +207,6 @@ func (rp *MemProvider) SessionAll() int { ...@@ -196,15 +207,6 @@ func (rp *MemProvider) SessionAll() int {
196 return 0 207 return 0
197 } 208 }
198 209
199 // connect to memcache and keep the connection.
200 func (rp *MemProvider) connectInit() (*memcache.Connection, error) {
201 c, err := memcache.Connect(rp.savePath)
202 if err != nil {
203 return nil, err
204 }
205 return c, nil
206 }
207
208 func init() { 210 func init() {
209 session.Register("memcache", mempder) 211 session.Register("memcache", mempder)
210 } 212 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!