Go基础学习记录之Session存储

栏目: Go · 发布时间: 5年前

内容简介:我们在上篇文章中介绍了一个简单的Session管理器的工作原理,除此之外,我们还定义了一个Session存储接口。在本次分享中,我将展示一个实现此接口的基于内存的会话存储引擎的示例。您也可以将其定制为其他形式的Session存储。上面的示例实现了基于内存的Session存储机制。它使用其init()函数将此存储引擎注册到Session管理器。那么我们如何从主程序注册这个引擎呢?我们使用空白导入机制(它将自动调用包的init()函数)将此引擎注册到Session管理器。然后,我们使用以下代码初始化Sessi

Session存储

我们在上篇文章中介绍了一个简单的Session管理器的工作原理,除此之外,我们还定义了一个Session存储接口。在本次分享中,我将展示一个实现此接口的基于内存的会话存储引擎的示例。您也可以将其定制为其他形式的Session存储。

package memory

import (
    "container/list"
    "sync"
    "time"

    "github.com/durban89/wiki/session"
)

// Store 存储
type Store struct {
    sid      string                      // unique session is
    lastTime time.Time                   // last save time
    value    map[interface{}]interface{} // session value save inside
}

// Provider 寄存器
type Provider struct {
    lock     sync.RWMutex             // locker
    sessions map[string]*list.Element // map in memory
    list     *list.List               // for gc
}

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

// Set Session
func (s *Store) Set(key, value interface{}) error {
    s.value[key] = value
    memoryProvider.SessionUpdate(s.sid)
    return nil
}

// Get Session
func (s *Store) Get(key interface{}) interface{} {
    memoryProvider.SessionUpdate(s.sid)
    if v, ok := s.value[key]; ok {
        return v
    }

    return nil

}

// Del Session
func (s *Store) Del(key interface{}) error {
    delete(s.value, key)
    memoryProvider.SessionUpdate(s.sid)
    return nil
}

// SID Session ID
func (s *Store) SID() string {
    return s.sid
}

// SessionInit 一个Session
func (p *Provider) SessionInit(sid string) (session.Session, error) {
    memoryProvider.lock.Lock()
    defer memoryProvider.lock.Unlock()
    v := make(map[interface{}]interface{}, 0)
    store := &Store{
        sid:      sid,
        lastTime: time.Now(),
        value:    v,
    }

    res := memoryProvider.list.PushBack(store)
    memoryProvider.sessions[sid] = res

    return store, nil
}

// SessionRead 一个Session
func (p *Provider) SessionRead(sid string) (session.Session, error) {
    if v, ok := memoryProvider.sessions[sid]; ok {
        return v.Value.(*Store), nil
    }

    store, err := memoryProvider.SessionInit(sid)
    return store, err

}

// SessionDestroy 一个Session
func (p *Provider) SessionDestroy(sid string) error {
    if v, ok := memoryProvider.sessions[sid]; ok {
        delete(memoryProvider.sessions, sid)
        memoryProvider.list.Remove(v)
        return nil
    }

    return nil
}

// SessionGC 一个Session
func (p *Provider) SessionGC(maxLifeTime int64) {
    memoryProvider.lock.Lock()
    defer memoryProvider.lock.Unlock()

    for {
        v := memoryProvider.list.Back()
        if v == nil {
            break
        }

        if v.Value.(*Store).lastTime.Unix()+maxLifeTime < time.Now().Unix() {
            memoryProvider.list.Remove(v)
            delete(memoryProvider.sessions, v.Value.(*Store).sid)
        } else {
            break
        }
    }
}

// SessionUpdate 一个Session
func (p *Provider) SessionUpdate(sid string) error {
    memoryProvider.lock.Lock()
    defer memoryProvider.lock.Unlock()

    if v, ok := memoryProvider.sessions[sid]; ok {
        v.Value.(*Store).lastTime = time.Now()
        memoryProvider.list.MoveToFront(v)
    }

    return nil
}

func init() {
    memoryProvider.sessions = make(map[string]*list.Element, 0)
    session.RegisterProvider("memory", memoryProvider)
}

上面的示例实现了基于内存的Session存储机制。它使用其init()函数将此存储引擎注册到Session管理器。那么我们如何从主程序注册这个引擎呢?

import (
    "github.com/durban89/wiki/session"

    // memory session provider
    _ "github.com/durban89/wiki/session/providers/memory"
)

我们使用空白导入机制(它将自动调用包的init()函数)将此引擎注册到Session管理器。然后,我们使用以下代码初始化Session管理器:

var appSession *session.Manager

func init() {
    appSession, _ := session.GetManager("memory", "sessionid", 3600)

    go appSession.SessionGC()
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JavaScript忍者秘籍

JavaScript忍者秘籍

John Resig、Bear Bibeault / 徐涛 / 人民邮电出版社 / 2015-10 / 69.00

JavaScript语言非常重要,相关的技术图书也很多,但没有任何一本书对JavaScript语言的重要部分(函数、闭包和原型)进行深入、全面的介绍,也没有任何一本书讲述跨浏览器代码的编写。本书是jQuery库创始人编写的一本深入剖析JavaScript语言的书。 本书共分四个部分,从准入训练、见习训练、忍者训练和火影训练四个层次讲述了逐步成为JavaScript高手的全过程。全书从高级We......一起来看看 《JavaScript忍者秘籍》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具