providers/session: Fully-working session system

This commit is contained in:
Sasha Koshka 2024-12-14 01:06:43 -05:00
parent 9858fc4f17
commit 3cc005bece

View File

@ -64,8 +64,8 @@ func (this *Provider) FuncMapFor (document *step.Document) template.FuncMap {
sessions: &this.sessions, sessions: &this.sessions,
} }
return template.FuncMap { return template.FuncMap {
"sessionHTTP": stat.funcSessionHTTP, "sessionHTTP": stat.funcSessionHTTP,
"session": stat.funcSession, "session": stat.funcSession,
} }
} }
@ -94,14 +94,17 @@ func (this *state) funcSessionHTTP (
} else { } else {
expiration = time.Now().Add(this.lifetime) expiration = time.Now().Add(this.lifetime)
} }
var result *session var result *Session
if session, ok := this.checkSession(id); ok { if session, ok := this.checkSession(id); ok {
if this.lifetime != 0 { if this.lifetime != 0 {
session.setExpiration(expiration) session.setExpiration(expiration)
} }
result = session result = session
} else { } else {
session, err := this.startSession(expiration) if id == (uuid.UUID { }) {
id = uuid.New()
}
session, err := this.newSession(id, expiration)
if err != nil { return nil, err } if err != nil { return nil, err }
result = session result = session
} }
@ -114,42 +117,33 @@ func (this *state) funcSessionHTTP (
return result, nil return result, nil
} }
func (this *state) funcSession (id uuid.UUID) (*session, error) { func (this *state) funcSession (id uuid.UUID) (*Session, error) {
expires := time.Now().Add(this.lifetime) expires := time.Now().Add(this.lifetime)
if session, ok := this.checkSession(id); ok { if session, ok := this.checkSession(id); ok {
session.setExpiration(expires) session.setExpiration(expires)
return session, nil return session, nil
} }
return this.startSession(expires) return this.newSession(id, expires)
} }
func (this *state) checkSession (id uuid.UUID) (*session, bool) { func (this *state) checkSession (id uuid.UUID) (*Session, bool) {
sessions, done := this.sessions.RBorrow() sessions, done := this.sessions.RBorrow()
defer done() defer done()
session, ok := sessions[id] session, ok := sessions[id]
log.Println(ok)
if !ok || session.Expired() { return nil, false } if !ok || session.Expired() { return nil, false }
return session, true return session, true
} }
func (this *state) startSession (expires time.Time) (*session, error) { func (this *state) newSession (id uuid.UUID, expires time.Time) (*Session, error) {
sessions, done := this.sessions.Borrow() return &Session {
defer done()
id := uuid.New()
// air defense
if _, exists := sessions[id]; exists { return nil, step.ErrPigsFlying }
session := &Session {
parent: this, parent: this,
id: id, id: id,
data: usync.NewRWLocker(make(map[string] any)), data: usync.NewRWLocker(make(map[string] any)),
expires: usync.NewRWLocker(expires), expires: usync.NewRWLocker(expires),
} }, nil
sessions[id] = session
log.Println(id)
return session, nil
} }
type sessionMap = map[uuid.UUID] *Session type sessionMap map[uuid.UUID] *Session
type Session struct { type Session struct {
parent *state // immutable parent *state // immutable
@ -172,6 +166,7 @@ func (this *Session) Set (name string, value any) string {
data, done := this.data.Borrow() data, done := this.data.Borrow()
defer done() defer done()
data[name] = value data[name] = value
this.addSelf()
return "" return ""
} }
@ -186,17 +181,27 @@ func (this *Session) Clear () string {
data, done := this.data.Borrow() data, done := this.data.Borrow()
defer done() defer done()
clear(data) clear(data)
this.delSelf()
return "" return ""
} }
func (this *Session) Close () (string, error) { func (this *Session) String () string {
return this.id.String()
}
func (this *Session) addSelf () (string, error) {
sessions, done := this.parent.sessions.Borrow()
defer done()
sessions[this.id] = this
log.Println("ADD", sessions)
return "", nil
}
func (this *Session) delSelf () (string, error) {
sessions, done := this.parent.sessions.Borrow() sessions, done := this.parent.sessions.Borrow()
defer done() defer done()
if _, ok := sessions[this.id]; ok {
return "", step.ErrDoubleClose
}
delete(sessions, this.id) delete(sessions, this.id)
this.Clear() log.Println("DEL", sessions)
return "", nil return "", nil
} }
@ -215,5 +220,5 @@ func (this *Session) setExpiration (expires time.Time) string {
} }
func (this *Session) Expired () bool { func (this *Session) Expired () bool {
return this.Expiration().After(time.Now()) return this.Expiration().Before(time.Now())
} }