cookie管理(2) session存储于内存

package memoryprovider

import (
    "container/list"
    "log"
    "sync"
    "time"
    "xapp/components/httpmod/http/session"
)

type MemorySessionProvider struct {
    lock     sync.Mutex
    sessions map[string]*list.Element
    elList   *list.List
}

var providerInst = &MemorySessionProvider{
    elList:   list.New(),
    sessions: make(map[string]*list.Element),
}

func providerInstance() *MemorySessionProvider {
    return providerInst
}

var registerMemoryProvider sync.Once

func DoRegister() {
    registerMemoryProvider.Do(func() {
        session.RegisterProvider("memory", providerInst)
    })
}

func (pder *MemorySessionProvider) SessionInit(sid string) (session.Session, error) {
    pder.lock.Lock()
    defer pder.lock.Unlock()
    newsess := &SessionStore{
        sid:          sid,
        timeAccessed: time.Now(),
        infoColl:     make(map[interface{}]interface{}, 0),
    }
    element := pder.elList.PushBack(newsess)
    pder.sessions[sid] = element
    return newsess, nil
}

func (pder *MemorySessionProvider) SessionRead(sid string) (session.Session, error) {
    if sess := pder.loadExistingSession(sid); sess != nil {
        return sess, nil
    }
    return pder.SessionInit(sid)
}

func (pder *MemorySessionProvider) loadExistingSession(sid string) session.Session {
    pder.lock.Lock()
    defer pder.lock.Unlock()
    if element, ok := pder.sessions[sid]; ok {
        return element.Value.(*SessionStore)
    }
    return nil
}

func (pder *MemorySessionProvider) SessionDestroy(sid string) error {
    pder.lock.Lock()
    defer pder.lock.Unlock()
    if element, ok := pder.sessions[sid]; ok {
        delete(pder.sessions, sid)
        pder.elList.Remove(element)
    }
    return nil
}

// maxlifetime in milliseconds
func (pder *MemorySessionProvider) SessionGC(maxlifetime int64) {
    pder.lock.Lock()
    defer pder.lock.Unlock()

    log.Println("list len is now:", pder.elList.Len())
    for {
        element := pder.elList.Back()
        if element == nil {
            break
        }
        ss := element.Value.(*SessionStore)
        if ss.timeAccessed.Unix()*1000+maxlifetime < time.Now().Unix()*1000 {
            pder.elList.Remove(element)
            delete(pder.sessions, ss.sid)
        } else {
            break
        }
    }
    log.Println("list len(after gc):", pder.elList.Len())
}

func (pder *MemorySessionProvider) SessionUpdate(sid string) {
    pder.lock.Lock()
    defer pder.lock.Unlock()
    if element, ok := pder.sessions[sid]; ok {
        element.Value.(*SessionStore).timeAccessed = time.Now()
        pder.elList.MoveToFront(element)
    }
}

单个的Session:

package memoryprovider

import (
    "time"
)

type SessionStore struct {
    sid          string                      // unique session id
    timeAccessed time.Time                   // last access time
    infoColl     map[interface{}]interface{} // session value stored inside
}

func (st *SessionStore) Set(key, value interface{}) error {
    st.infoColl[key] = value
    providerInstance().SessionUpdate(st.sid)
    return nil
}

func (st *SessionStore) Get(key interface{}) interface{} {
    providerInstance().SessionUpdate(st.sid)
    if v, ok := st.infoColl[key]; ok {
        return v
    } else {
        return nil
    }
    return nil
}

func (st *SessionStore) Delete(key interface{}) error {
    delete(st.infoColl, key)
    providerInstance().SessionUpdate(st.sid)
    return nil
}

func (st *SessionStore) SessionID() string {
    return st.sid
}

你可能感兴趣的:(golang)