iris/sessions/sessiondb/redis/database.go
Gerasimos (Makis) Maropoulos 7989a2fd72 fix https://github.com/kataras/iris/issues/771
Former-commit-id: 5659b6ca274bb51d7de0d079b0e87c0c513540a6
2017-09-30 23:52:32 +03:00

109 lines
2.6 KiB
Go

package redis
import (
"runtime"
"time"
"github.com/kataras/golog"
"github.com/kataras/iris/sessions"
"github.com/kataras/iris/sessions/sessiondb/redis/service"
)
// Database the redis back-end session database for the sessions.
type Database struct {
redis *service.Service
async bool
}
// New returns a new redis database.
func New(cfg ...service.Config) *Database {
db := &Database{redis: service.New(cfg...)}
runtime.SetFinalizer(db, closeDB)
return db
}
// Config returns the configuration for the redis server bridge, you can change them.
func (db *Database) Config() *service.Config {
return db.redis.Config
}
// Async if true passed then it will use different
// go routines to update the redis storage.
func (db *Database) Async(useGoRoutines bool) *Database {
db.async = useGoRoutines
return db
}
// Load loads the values to the underline.
func (db *Database) Load(sid string) (storeDB sessions.RemoteStore) {
// values := make(map[string]interface{})
if !db.redis.Connected { //yes, check every first time's session for valid redis connection
db.redis.Connect()
_, err := db.redis.PingPong()
if err != nil {
golog.Errorf("redis database error on connect: %v", err)
return
}
}
// fetch the values from this session id and copy-> store them
storeMaybe, err := db.redis.Get(sid)
// exists
if err == nil {
storeB, ok := storeMaybe.([]byte)
if !ok {
golog.Errorf("something wrong, store should be stored as []byte but stored as %#v", storeMaybe)
return
}
storeDB, err = sessions.DecodeRemoteStore(storeB) // decode the whole value, as a remote store
if err != nil {
golog.Errorf(`error while trying to load session values(%s) from redis:
the retrieved value is not a sessions.RemoteStore type, please report that as bug, that should never occur: %v`,
sid, err)
}
}
return
}
// Sync syncs the database.
func (db *Database) Sync(p sessions.SyncPayload) {
if db.async {
go db.sync(p)
} else {
db.sync(p)
}
}
func (db *Database) sync(p sessions.SyncPayload) {
if p.Action == sessions.ActionDestroy {
db.redis.Delete(p.SessionID)
return
}
storeB, err := p.Store.Serialize()
if err != nil {
golog.Error("error while encoding the remote session store")
return
}
// not expire if zero
seconds := 0
if lifetime := p.Store.Lifetime; !lifetime.IsZero() {
seconds = int(lifetime.Sub(time.Now()).Seconds())
}
db.redis.Set(p.SessionID, storeB, seconds)
}
// Close shutdowns the redis connection.
func (db *Database) Close() error {
return closeDB(db)
}
func closeDB(db *Database) error {
return db.redis.CloseConnection()
}