package ghappman import ( "sync" "time" ) type sessionStore struct { sync.Mutex vals map[string]*session expires map[string]*time.Timer timeout time.Duration } type session struct { KeyHash []byte App *AppConfig } func newSessionStore(timeout time.Duration) *sessionStore { return &sessionStore{ vals: make(map[string]*session), expires: make(map[string]*time.Timer), timeout: timeout, } } func (s *sessionStore) startSession(key string, hash []byte) { s.Lock() s.vals[key] = &session{ KeyHash: hash, } t := time.AfterFunc(s.timeout, func() { s.endSession(key) }) s.expires[key] = t s.Unlock() } func (s *sessionStore) updateSession(key string, app *AppConfig) { s.Lock() s.vals[key].App = app s.Unlock() } func (s *sessionStore) endSession(key string) { s.Lock() if t := s.expires[key]; t != nil { // if the session timed out, t.Stop() will be a nop because // the timeout timer already reached its end. repeated calls to endSession // with the same key or non-existent key will produce a nil timer _ = t.Stop() } delete(s.expires, key) delete(s.vals, key) s.Unlock() } func (s *sessionStore) getSession(key string) *session { s.Lock() defer s.Unlock() return s.vals[key] } func (s *sessionStore) hasSession(key string) bool { s.Lock() defer s.Unlock() return s.vals[key] != nil }