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