Merge pull request #14540 from grafana/session-skip-update

only update session in mysql database when required
This commit is contained in:
Dan Cech 2018-12-31 11:54:04 -05:00 committed by GitHub
commit efa738ddf6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -33,14 +33,18 @@ type MysqlStore struct {
sid string sid string
lock sync.RWMutex lock sync.RWMutex
data map[interface{}]interface{} data map[interface{}]interface{}
expiry int64
dirty bool
} }
// NewMysqlStore creates and returns a mysql session store. // NewMysqlStore creates and returns a mysql session store.
func NewMysqlStore(c *sql.DB, sid string, kv map[interface{}]interface{}) *MysqlStore { func NewMysqlStore(c *sql.DB, sid string, kv map[interface{}]interface{}, expiry int64) *MysqlStore {
return &MysqlStore{ return &MysqlStore{
c: c, c: c,
sid: sid, sid: sid,
data: kv, data: kv,
expiry: expiry,
dirty: false,
} }
} }
@ -50,6 +54,7 @@ func (s *MysqlStore) Set(key, val interface{}) error {
defer s.lock.Unlock() defer s.lock.Unlock()
s.data[key] = val s.data[key] = val
s.dirty = true
return nil return nil
} }
@ -67,6 +72,7 @@ func (s *MysqlStore) Delete(key interface{}) error {
defer s.lock.Unlock() defer s.lock.Unlock()
delete(s.data, key) delete(s.data, key)
s.dirty = true
return nil return nil
} }
@ -77,13 +83,20 @@ func (s *MysqlStore) ID() string {
// Release releases resource and save data to provider. // Release releases resource and save data to provider.
func (s *MysqlStore) Release() error { func (s *MysqlStore) Release() error {
newExpiry := time.Now().Unix()
if !s.dirty && (s.expiry+60) >= newExpiry {
return nil
}
data, err := session.EncodeGob(s.data) data, err := session.EncodeGob(s.data)
if err != nil { if err != nil {
return err return err
} }
_, err = s.c.Exec("UPDATE session SET data=?, expiry=? WHERE `key`=?", _, err = s.c.Exec("UPDATE session SET data=?, expiry=? WHERE `key`=?",
data, time.Now().Unix(), s.sid) data, newExpiry, s.sid)
s.dirty = false
s.expiry = newExpiry
return err return err
} }
@ -93,6 +106,7 @@ func (s *MysqlStore) Flush() error {
defer s.lock.Unlock() defer s.lock.Unlock()
s.data = make(map[interface{}]interface{}) s.data = make(map[interface{}]interface{})
s.dirty = true
return nil return nil
} }
@ -117,11 +131,12 @@ func (p *MysqlProvider) Init(expire int64, connStr string) (err error) {
// Read returns raw session store by session ID. // Read returns raw session store by session ID.
func (p *MysqlProvider) Read(sid string) (session.RawStore, error) { func (p *MysqlProvider) Read(sid string) (session.RawStore, error) {
expiry := time.Now().Unix()
var data []byte var data []byte
err := p.c.QueryRow("SELECT data FROM session WHERE `key`=?", sid).Scan(&data) err := p.c.QueryRow("SELECT data,expiry FROM session WHERE `key`=?", sid).Scan(&data, &expiry)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
_, err = p.c.Exec("INSERT INTO session(`key`,data,expiry) VALUES(?,?,?)", _, err = p.c.Exec("INSERT INTO session(`key`,data,expiry) VALUES(?,?,?)",
sid, "", time.Now().Unix()) sid, "", expiry)
} }
if err != nil { if err != nil {
return nil, err return nil, err
@ -137,7 +152,7 @@ func (p *MysqlProvider) Read(sid string) (session.RawStore, error) {
} }
} }
return NewMysqlStore(p.c, sid, kv), nil return NewMysqlStore(p.c, sid, kv, expiry), nil
} }
// Exist returns true if session with given ID exists. // Exist returns true if session with given ID exists.