Go基础学习记录之Session存储

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

内容简介:我们在上篇文章中介绍了一个简单的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()
}

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

查看所有标签

猜你喜欢:

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

精通Java并发编程(第2版)

精通Java并发编程(第2版)

[西] 哈维尔·费尔南德斯·冈萨雷斯 / 唐富年 / 人民邮电出版社 / 2018-10 / 89.00元

Java 提供了一套非常强大的并发API,可以轻松实现任何类型的并发应用程序。本书讲述Java 并发API 最重要的元素,包括执行器框架、Phaser 类、Fork/Join 框架、流API、并发数据结构、同步机制,并展示如何在实际开发中使用它们。此外,本书还介绍了设计并发应用程序的方法论、设计模式、实现良好并发应用程序的提示和技巧、测试并发应用程序的工具和方法,以及如何使用面向Java 虚拟机的......一起来看看 《精通Java并发编程(第2版)》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具