github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/prepare/05_session/session/memory/memory.go (about)

     1  // session 内存方式的存储实现
     2  package memory
     3  
     4  import (
     5  	"container/list"
     6  	"fmt"
     7  	"github.com/qiuhoude/go-web/prepare/05_session/session"
     8  	"sync"
     9  	"time"
    10  )
    11  
    12  var pder = &Provider{list: list.New()}
    13  
    14  type (
    15  	//Session的实现
    16  	SessionStore struct {
    17  		sid          string                      //session id唯一标示
    18  		timeAccessed time.Time                   //最后访问时间
    19  		value        map[interface{}]interface{} //session里面存储的值
    20  	}
    21  	// Provider的实现
    22  	Provider struct {
    23  		lock     sync.Mutex               //用来锁
    24  		sessions map[string]*list.Element //用来存储在内存
    25  		list     *list.List               //用来做gc
    26  	}
    27  )
    28  
    29  func (pder *Provider) SessionInit(sid string) (session.Session, error) {
    30  	pder.lock.Lock()
    31  	defer pder.lock.Unlock()
    32  	v := make(map[interface{}]interface{}, 0)
    33  	newsess := &SessionStore{sid: sid, timeAccessed: time.Now(), value: v}
    34  	element := pder.list.PushBack(newsess)
    35  	pder.sessions[sid] = element
    36  	return newsess, nil
    37  }
    38  
    39  func (pder *Provider) SessionRead(sid string) (session.Session, error) {
    40  	if element, ok := pder.sessions[sid]; ok {
    41  		return element.Value.(*SessionStore), nil
    42  	} else {
    43  		sess, err := pder.SessionInit(sid)
    44  		return sess, err
    45  	}
    46  	return nil, nil
    47  }
    48  
    49  func (pder *Provider) SessionDestroy(sid string) error {
    50  	pder.lock.Lock()
    51  	defer pder.lock.Unlock()
    52  
    53  	if element, ok := pder.sessions[sid]; ok {
    54  		delete(pder.sessions, sid)
    55  		pder.list.Remove(element)
    56  		return nil
    57  	}
    58  	return nil
    59  }
    60  
    61  func (pder *Provider) SessionGC(maxlifetime int64) {
    62  	pder.lock.Lock()
    63  	defer pder.lock.Unlock()
    64  
    65  	for {
    66  		element := pder.list.Back()
    67  		if element == nil { // 从link 后往前找, list是个双端列表 root element持有首端和尾端
    68  			break
    69  		}
    70  		if (element.Value.(*SessionStore).timeAccessed.Unix() + maxlifetime) < time.Now().Unix() {
    71  			// 最后一次访问session时间 + 最大存活时间 < 现在时间 ;说明session过期了进行移除
    72  			pder.list.Remove(element)
    73  			delete(pder.sessions, element.Value.(*SessionStore).sid)
    74  		} else {
    75  			break
    76  		}
    77  
    78  	}
    79  }
    80  
    81  // 更新最后一次访问时间
    82  func (pder *Provider) SessionUpdate(sid string) error {
    83  	pder.lock.Lock()
    84  	defer pder.lock.Unlock()
    85  
    86  	if element, ok := pder.sessions[sid]; ok {
    87  		element.Value.(*SessionStore).timeAccessed = time.Now()
    88  		pder.list.MoveToFront(element)
    89  		return nil
    90  	}
    91  	return nil
    92  }
    93  
    94  func (st *SessionStore) Set(key, value interface{}) error {
    95  	st.value[key] = value
    96  	pder.SessionUpdate(st.sid)
    97  	return nil
    98  }
    99  
   100  func (st *SessionStore) Get(key interface{}) interface{} {
   101  	pder.SessionUpdate(st.sid)
   102  	if v, ok := st.value[key]; ok {
   103  		return v
   104  	} else {
   105  		return nil
   106  	}
   107  	return nil
   108  }
   109  
   110  func (st *SessionStore) Delete(key interface{}) error {
   111  	delete(st.value, key)
   112  	pder.SessionUpdate(st.sid)
   113  	return nil
   114  }
   115  
   116  func (st *SessionStore) SessionID() string {
   117  	return st.sid
   118  }
   119  
   120  func init() {
   121  	pder.sessions = make(map[string]*list.Element, 0)
   122  	session.Register("memory", pder)
   123  	fmt.Println("memory包。。init,")
   124  }