All files and memory storage tests pass
This commit is contained in:
parent
045163310e
commit
23b020ec9b
4 changed files with 72 additions and 46 deletions
|
@ -5,13 +5,13 @@ import (
|
|||
"bytes"
|
||||
"container/list"
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
//"git.mtux.eu/darkgopher/session"
|
||||
"git.mtux.eu/darkgopher/session"
|
||||
"github.com/djherbis/atime"
|
||||
)
|
||||
|
@ -21,10 +21,10 @@ const (
|
|||
sessExt string = "gsd"
|
||||
)
|
||||
|
||||
var pder *ProviderFiles
|
||||
var pder = &ProviderFiles{li: list.New()}
|
||||
|
||||
func init() {
|
||||
pder = &ProviderFiles{}
|
||||
pder.sessions = make(map[string]*list.Element, 0)
|
||||
session.Register("files", pder)
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,8 @@ func ckdirpath(sid string) string {
|
|||
// ProviderFiles implement filesystem session provider
|
||||
type ProviderFiles struct {
|
||||
lock sync.Mutex
|
||||
li *list.List //or gc
|
||||
sessions map[string]*list.Element
|
||||
list *list.List //or gc
|
||||
sessPath string
|
||||
}
|
||||
|
||||
|
@ -56,15 +56,19 @@ func (pder *ProviderFiles) SetParams(p any) (err error) {
|
|||
if p != nil {
|
||||
if s, ok := p.(string); ok {
|
||||
pder.sessPath = s
|
||||
sdir := path.Join(pder.sessPath, sessDir)
|
||||
if err = os.MkdirAll(sdir, 0o700); err != nil {
|
||||
return fmt.Errorf("make session directory path: %s failed: %v", sdir, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
return fmt.Errorf("parameter for files session provider is not string")
|
||||
}
|
||||
return fmt.Errorf("parameter for files session provider must be provided, not nil")
|
||||
return fmt.Errorf("parameter for files session provider must be provided")
|
||||
}
|
||||
|
||||
// Init create empty session file if not exists and retturn *Session
|
||||
func (pder *ProviderFiles) Init(sid string) (sess session.Session, err error) {
|
||||
func (pder *ProviderFiles) Init(sid string) (ses session.Session, err error) {
|
||||
pder.lock.Lock()
|
||||
defer pder.lock.Unlock()
|
||||
var fd *os.File
|
||||
|
@ -73,8 +77,8 @@ func (pder *ProviderFiles) Init(sid string) (sess session.Session, err error) {
|
|||
return nil, fmt.Errorf("create session file: %s failed with err: %w", ckf, err)
|
||||
}
|
||||
defer fd.Close()
|
||||
sess = &SessionFile{sid}
|
||||
ssel := pder.list.PushBack(sess)
|
||||
sess := &SessionFile{sid}
|
||||
ssel := pder.li.PushBack(sess)
|
||||
pder.sessions[sid] = ssel
|
||||
return sess, nil
|
||||
}
|
||||
|
@ -84,7 +88,9 @@ func (pder *ProviderFiles) Load(sid string) (sess session.Session, err error) {
|
|||
pder.lock.Lock()
|
||||
defer pder.lock.Unlock()
|
||||
if pder.Exists(sid) {
|
||||
return pder.sessions[sid].Value.(*SessionFile), nil
|
||||
if sesel, ok := pder.sessions[sid]; ok {
|
||||
return sesel.Value.(*SessionFile), nil
|
||||
}
|
||||
}
|
||||
return pder.Init(sid)
|
||||
}
|
||||
|
@ -96,7 +102,7 @@ func (pder *ProviderFiles) Destroy(sid string) (err error) {
|
|||
if pder.Exists(sid) {
|
||||
ssel := pder.sessions[sid]
|
||||
delete(pder.sessions, sid)
|
||||
pder.list.Remove(ssel)
|
||||
pder.li.Remove(ssel)
|
||||
return os.Remove(ckdirpath(sid))
|
||||
}
|
||||
return
|
||||
|
@ -108,7 +114,7 @@ func (pder *ProviderFiles) ChangeID(oldsid, newsid string) (err error) {
|
|||
ckfold := ckdirpath(oldsid)
|
||||
ckfnew := ckdirpath(newsid)
|
||||
if err = os.Rename(ckfold, ckfnew); err != nil {
|
||||
return fmt.Errorf("Rename cookie file: %s to: %s failed: %v", ckfold, ckfnew, err)
|
||||
return fmt.Errorf("rename cookie file: %s to: %s failed: %v", ckfold, ckfnew, err)
|
||||
}
|
||||
ssel.Value.(*SessionFile).sid = newsid
|
||||
delete(pder.sessions, oldsid)
|
||||
|
@ -117,21 +123,29 @@ func (pder *ProviderFiles) ChangeID(oldsid, newsid string) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Exists check if session sid exists in storage
|
||||
// Exists return true if session with sid exists
|
||||
func (pder *ProviderFiles) Exists(sid string) (ex bool) {
|
||||
if _, ex := pder.sessions[sid]; ex {
|
||||
return ex
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*// Exists check if session sid exists in storage
|
||||
func (pder *ProviderFiles) Exists(sid string) bool {
|
||||
ckf := ckdirpath(sid)
|
||||
if _, err := os.Stat(ckf); errors.Is(err, os.ErrExist) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}*/
|
||||
|
||||
// GC periodically remove old sessions rom storages
|
||||
func (pder *ProviderFiles) GC(maxlifetime int64) {
|
||||
pder.lock.Lock()
|
||||
defer pder.lock.Unlock()
|
||||
for {
|
||||
ssel := pder.list.Back()
|
||||
ssel := pder.li.Back()
|
||||
if ssel == nil {
|
||||
break
|
||||
}
|
||||
|
@ -142,10 +156,13 @@ func (pder *ProviderFiles) GC(maxlifetime int64) {
|
|||
continue
|
||||
}
|
||||
if at.UnixMilli()+(maxlifetime*session.MilisPerSec()) < time.Now().UnixMilli() {
|
||||
pder.list.Remove(ssel)
|
||||
log.Printf("GC remove session: %s atime: %v now: %v", sid, at, time.Now())
|
||||
pder.li.Remove(ssel)
|
||||
delete(pder.sessions, sid)
|
||||
ckf := ckdirpath(sid)
|
||||
os.Remove(ckf)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -159,6 +176,7 @@ type SessionFile struct {
|
|||
func (sf *SessionFile) loadFromFile() (data map[any]any, err error) {
|
||||
var sb []byte
|
||||
sfp := ckdirpath(sf.sid)
|
||||
data = make(map[any]any, 0)
|
||||
if sb, err = os.ReadFile(sfp); err != nil {
|
||||
return nil, fmt.Errorf("session file: %s read error: %v", sf.sid, err)
|
||||
}
|
||||
|
@ -166,9 +184,12 @@ func (sf *SessionFile) loadFromFile() (data map[any]any, err error) {
|
|||
if _, err = gobdata.Write(sb); err != nil {
|
||||
return nil, fmt.Errorf("load session file: %s into buffer err: %v", sf.sid, err)
|
||||
}
|
||||
if gobdata.Len() == 0 {
|
||||
return data, nil
|
||||
}
|
||||
dec := gob.NewDecoder(&gobdata)
|
||||
if err = dec.Decode(&data); err != nil {
|
||||
return nil, fmt.Errorf("decode gob data from file: %s error: %v", sf.sid, err)
|
||||
return nil, fmt.Errorf("decode gob data: %d from file: %s error: %v", gobdata.Len(), sf.sid, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue