package main import ( "crypto/md5" "fmt" "math/rand" "time" "redisdog/model" ) type Session struct { Sess string `json:"sess"` Expire int64 `json:"expire"` Account *model.AccountsRow `json:"account"` } type SessionPoll struct { poll map[string]*Session lock chan int ttl int64 } func NewSessionPoll(ttl int64) *SessionPoll { p := &SessionPoll{ poll: make(map[string]*Session, 1024), lock: make(chan int, 1), ttl: ttl, } go p.timer() return p } func (p *SessionPoll) timer() { for { time.Sleep(time.Minute * 1) ts := time.Now().Unix() expired := make([]string, len(p.poll)) cnt := 0 p.lock <- 1 for id, s := range p.poll { if s.Expire <= ts { expired[cnt] = id cnt++ } } for _, id := range expired { delete(p.poll, id) } <-p.lock } } func (p *SessionPoll) Get(sessid string) (*Session, bool) { p.lock <- 1 s, ok := p.poll[sessid] if ok { p.poll[sessid].Expire = time.Now().Unix() + p.ttl } <-p.lock return s, ok } func (p *SessionPoll) Set(sessid string, sess *Session) { if sess.Expire == 0 { sess.Expire = time.Now().Unix() + p.ttl } p.lock <- 1 p.poll[sessid] = sess <-p.lock } func (p *SessionPoll) Del(sessid string) { p.lock <- 1 delete(p.poll, sessid) <-p.lock } func makeSessionId(cliAddr string) string { return fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("sess|%s|%d|d", cliAddr, time.Now().Unix(), rand.Int63())))) }