Skip to content
Snippets Groups Projects
Commit 589d6ba8 authored by Christian Pointner's avatar Christian Pointner
Browse files

improved session expiry... needs testing and some thougts!

parent 930736e7
No related branches found
No related tags found
No related merge requests found
......@@ -82,7 +82,7 @@ type Session struct {
ID string
state SessionState
Expires time.Time
expires atomic.Value
Username string
ReadOnly bool
AllShows bool
......@@ -101,6 +101,7 @@ func NewSession() (s *Session, err error) {
return
}
s.setState(SessionStateNew)
s.setExpires(&time.Time{})
return
}
......@@ -115,25 +116,40 @@ func (s *Session) State() SessionState {
}
func (s *Session) setState(st SessionState) {
// TODO: notify subscribers! Check for subscriber channel will be racy...
atomic.StoreUint32((*uint32)(&s.state), uint32(st))
}
func (s *Session) updateState(old, new SessionState) bool {
// TODO: notify subscribers! Check for subscriber channel will be racy...
return atomic.CompareAndSwapUint32((*uint32)(&s.state), uint32(old), uint32(new))
}
func (s *Session) Expires() *time.Time {
exp := s.expires.Load()
if exp == nil {
return nil
}
return exp.(*time.Time)
}
func (s *Session) setExpires(exp *time.Time) {
s.expires.Store(exp)
}
func (s *Session) Expired() bool {
if s.Expires.IsZero() {
exp := s.Expires()
if exp == nil {
return false
}
return s.Expires.Before(time.Now())
return exp.Before(time.Now())
}
func (s *Session) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
ID string `json:"id"`
State SessionState `json:"state"`
Expires time.Time `json:"expires,omitempty"`
Expires *time.Time `json:"expires,omitempty"`
Username string `json:"username"`
ReadOnly bool `json:"readonly"`
AllShows bool `json:"all-shows"`
......@@ -141,7 +157,7 @@ func (s *Session) MarshalJSON() ([]byte, error) {
}{
ID: s.ID,
State: s.State(),
Expires: s.Expires,
Expires: s.Expires(),
Username: s.Username,
ReadOnly: s.ReadOnly,
AllShows: s.AllShows,
......@@ -228,10 +244,10 @@ func (sm *SessionManager) runMaintenance() {
}
func (sm *SessionManager) insert(s *Session) (err error) {
now := time.Now()
eMax := now.Add(sm.maxAge)
if s.Expires.Before(now) || s.Expires.After(eMax) {
s.Expires = eMax
eMax := time.Now().Add(sm.maxAge)
exp := s.Expires()
if exp != nil && (exp.IsZero() || exp.After(eMax)) {
s.setExpires(&eMax)
}
sm.mutex.Lock()
......@@ -273,9 +289,11 @@ func (sm *SessionManager) update(id string, s *Session) error {
if !ok {
return errors.New("session not found.")
}
if s.Expires.IsZero() {
s.Expires = old.Expires
}
// TODO: figure out how to handle expiry on update...
// exp := s.Expires()
// if exp != nil && exp.IsZero() {
// s.setExpires(old.Expires()) // TODO: enforce maxAge!
// }
s.secret = old.secret
s.ID = old.ID
if old.subscribe != nil {
......
......@@ -52,7 +52,11 @@ func TestSessionExpiry(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
s1 := &Session{Username: "test"}
s1, err := NewSession()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
s1.Username = "test"
if err = sm.insert(s1); err != nil {
t.Fatalf("unexpected error: %v", err)
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment