From b4a30f5af5d556cd3ff6e46e748125207899c86d Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Sat, 18 Aug 2018 15:01:26 +0300 Subject: [PATCH] sessions database: boltdb: add support for ShiftExpiration -> OnUpdateExpiration like redis badger sessiondb still in progress. Former-commit-id: 1f89a0efb753c0e02b774e0d9e48d879e987c939 --- sessions/database.go | 3 +-- sessions/sessiondb/boltdb/database.go | 36 +++++++++++++++++++++------ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/sessions/database.go b/sessions/database.go index 01830cfb..d4dfc644 100644 --- a/sessions/database.go +++ b/sessions/database.go @@ -32,8 +32,7 @@ type Database interface { // // Check of error is required, if error returned then the rest session's keys are not proceed. // - // Currently only "redis" database is designed to use that event. - // If A database is not support this feature then a `ErrNotImplemented` will be returned instead. + // If a database does not support this feature then an `ErrNotImplemented` will be returned instead. OnUpdateExpiration(sid string, newExpires time.Duration) error // Set sets a key value of a specific session. // The "immutable" input argument depends on the store, it may not implement it at all. diff --git a/sessions/sessiondb/boltdb/database.go b/sessions/sessiondb/boltdb/database.go index fd241cf6..fe1c90fe 100644 --- a/sessions/sessiondb/boltdb/database.go +++ b/sessions/sessiondb/boltdb/database.go @@ -210,10 +210,31 @@ func (db *Database) Acquire(sid string, expires time.Duration) (lifetime session return } -// OnUpdateExpiration not implemented here, yet. -// Note that this error will not be logged, callers should catch it manually. +// OnUpdateExpiration will re-set the database's session's entry ttl. func (db *Database) OnUpdateExpiration(sid string, newExpires time.Duration) error { - return sessions.ErrNotImplemented + expirationTime := time.Now().Add(newExpires) + timeBytes, err := sessions.DefaultTranscoder.Marshal(expirationTime) + if err != nil { + return err + } + + err = db.Service.Update(func(tx *bolt.Tx) error { + expirationName := getExpirationBucketName([]byte(sid)) + root := db.getBucket(tx) + b := root.Bucket(expirationName) + if b == nil { + // golog.Debugf("tried to reset the expiration value for '%s' while its configured lifetime is unlimited or the session is already expired and not found now", sid) + return sessions.ErrNotFound + } + + return b.Put(expirationKey, timeBytes) + }) + + if err != nil { + golog.Debugf("unable to reset the expiration value for '%s': %v", sid, err) + } + + return err } func makeKey(key string) []byte { @@ -306,14 +327,12 @@ func (db *Database) Len(sid string) (n int) { return } -var errNotFound = errors.New("not found") - // Delete removes a session key value based on its key. func (db *Database) Delete(sid string, key string) (deleted bool) { err := db.Service.Update(func(tx *bolt.Tx) error { b := db.getBucketForSession(tx, sid) if b == nil { - return errNotFound + return sessions.ErrNotFound } return b.Delete(makeKey(key)) @@ -343,12 +362,13 @@ func (db *Database) Release(sid string) { // delete the session bucket. b := db.getBucket(tx) bsid := []byte(sid) + // try to delete the associated expiration bucket, if exists, ignore error. + b.DeleteBucket(getExpirationBucketName(bsid)) + if err := b.DeleteBucket(bsid); err != nil { return err } - // and try to delete the associated expiration bucket, if exists, ignore error. - b.DeleteBucket(getExpirationBucketName(bsid)) return nil }) }