remove MaxAgeSeconds from redis sessiondb - now it derives from the sessions configuration automatically. Add option to use an existing BoltDB connection on boltdb sessiondb.

TODO: leveldb sessiondb

Former-commit-id: 8cb781bf089ab7b9a09dccc633454db9c6077610
This commit is contained in:
kataras 2017-08-08 12:31:42 +03:00
parent 48e352e1df
commit 92d0b146df
7 changed files with 70 additions and 43 deletions

1
.gitignore vendored
View File

@ -0,0 +1 @@
.vscode

View File

@ -11,15 +11,20 @@ import (
func main() {
// replace with your running redis' server settings:
db := redis.New(service.Config{Network: service.DefaultRedisNetwork,
Addr: service.DefaultRedisAddr,
Password: "",
Database: "",
MaxIdle: 0,
MaxActive: 0,
IdleTimeout: service.DefaultRedisIdleTimeout,
Prefix: "",
MaxAgeSeconds: service.DefaultRedisMaxAgeSeconds}) // optionally configure the bridge between your redis server
db := redis.New(service.Config{
Network: service.DefaultRedisNetwork,
Addr: service.DefaultRedisAddr,
Password: "",
Database: "",
MaxIdle: 0,
MaxActive: 0,
IdleTimeout: service.DefaultRedisIdleTimeout,
Prefix: ""}) // optionally configure the bridge between your redis server
// close connection when control+C/cmd+C
iris.RegisterOnInterrupt(func() {
db.Close()
})
sess := sessions.New(sessions.Config{Cookie: "sessionscookieid"})

View File

@ -31,7 +31,6 @@ import (
)
const (
// Version is the current version number of the Iris Web Framework.
Version = "8.2.0"
)

View File

@ -4,6 +4,7 @@ import (
"bytes"
"os"
"path/filepath"
"runtime"
"time"
"github.com/boltdb/bolt"
@ -21,11 +22,12 @@ var (
// Database the BoltDB(file-based) session storage.
type Database struct {
path string // path included the name, i.e sessions/store.db
fileMode os.FileMode // defaults to 0666.
table []byte
Service *bolt.DB // `New` sets it but it can be override exactly after `New`, use with caution.
async bool
table []byte
// Service is the underline BoltDB database connection,
// it's initialized at `New` or `NewFromDB`.
// Can be used to get stats.
Service *bolt.DB
async bool
}
var (
@ -58,22 +60,29 @@ func New(path string, fileMode os.FileMode, bucketName string) (*Database, error
&bolt.Options{Timeout: 15 * time.Second},
)
bucket := []byte(bucketName)
if err != nil {
golog.Errorf("unable to initialize the BoltDB-based session database: %v", err)
return nil, err
}
return NewFromDB(service, bucketName)
}
// NewFromDB same as `New` but accepts an already-created custom boltdb connection instead.
func NewFromDB(service *bolt.DB, bucketName string) (*Database, error) {
if bucketName == "" {
return nil, ErrOptionsMissing
}
bucket := []byte(bucketName)
service.Update(func(tx *bolt.Tx) (err error) {
_, err = tx.CreateBucketIfNotExists(bucket)
return
})
db := &Database{path: path, fileMode: fileMode,
table: bucket, Service: service,
}
db := &Database{table: bucket, Service: service}
runtime.SetFinalizer(db, closeDB)
return db, db.Cleanup()
}
@ -214,6 +223,10 @@ func (db *Database) Len() (num int) {
// Close shutdowns the BoltDB connection.
func (db *Database) Close() error {
return closeDB(db)
}
func closeDB(db *Database) error {
err := db.Service.Close()
if err != nil {
golog.Warnf("closing the BoltDB connection: %v", err)

View File

@ -1,6 +1,8 @@
package redis
import (
"runtime"
"github.com/kataras/golog"
"github.com/kataras/iris/sessions"
"github.com/kataras/iris/sessions/sessiondb/redis/service"
@ -14,10 +16,9 @@ type Database struct {
// New returns a new redis database.
func New(cfg ...service.Config) *Database {
return &Database{redis: service.New(cfg...)}
// Note: no need to clean up here, the redis should handle these automatically because of the "SETEX"
// but that expiration doesn't depend on the session, instead it depends on the `MaxAgeSeconds`
// of the redis database configuration.
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.
@ -83,5 +84,14 @@ func (db *Database) sync(p sessions.SyncPayload) {
return
}
db.redis.Set(p.SessionID, storeB)
db.redis.Set(p.SessionID, storeB, p.Store.Lifetime.Second())
}
// Close shutdowns the redis connection.
func (db *Database) Close() error {
return closeDB(db)
}
func closeDB(db *Database) error {
return db.redis.CloseConnection()
}

View File

@ -33,21 +33,18 @@ type Config struct {
IdleTimeout time.Duration
// Prefix "myprefix-for-this-website". Default ""
Prefix string
// MaxAgeSeconds how much long the redis should keep the session in seconds. Default 31556926.0 (1 year)
MaxAgeSeconds int
}
// DefaultConfig returns the default configuration for Redis service.
func DefaultConfig() Config {
return Config{
Network: DefaultRedisNetwork,
Addr: DefaultRedisAddr,
Password: "",
Database: "",
MaxIdle: 0,
MaxActive: 0,
IdleTimeout: DefaultRedisIdleTimeout,
Prefix: "",
MaxAgeSeconds: DefaultRedisMaxAgeSeconds,
Network: DefaultRedisNetwork,
Addr: DefaultRedisAddr,
Password: "",
Database: "",
MaxIdle: 0,
MaxActive: 0,
IdleTimeout: DefaultRedisIdleTimeout,
Prefix: "",
}
}

View File

@ -44,15 +44,21 @@ func (r *Service) CloseConnection() error {
// Set sets a key-value to the redis store.
// The expiration is setted by the MaxAgeSeconds.
func (r *Service) Set(key string, value interface{}) error {
func (r *Service) Set(key string, value interface{}, secondsLifetime int) (err error) {
c := r.pool.Get()
defer c.Close()
if c.Err() != nil {
return c.Err()
}
_, err := c.Do("SETEX", r.Config.Prefix+key, r.Config.MaxAgeSeconds, value)
return err
// if has expiration, then use the "EX" to delete the key automatically.
if secondsLifetime > 0 {
_, err = c.Do("SETEX", r.Config.Prefix+key, secondsLifetime, value)
} else {
_, err = c.Do("SET", r.Config.Prefix+key, value)
}
return
}
// Get returns value, err by its key
@ -164,10 +170,6 @@ func (r *Service) Connect() {
c.Addr = DefaultRedisAddr
}
if c.MaxAgeSeconds <= 0 {
c.MaxAgeSeconds = DefaultRedisMaxAgeSeconds
}
pool := &redis.Pool{IdleTimeout: DefaultRedisIdleTimeout, MaxIdle: c.MaxIdle, MaxActive: c.MaxActive}
pool.TestOnBorrow = func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")