From 29acea1e48cab6e2e52ec32b8b572cc80a76e964 Mon Sep 17 00:00:00 2001 From: Shin Kojima Date: Thu, 13 Jun 2013 23:23:34 +0900 Subject: [PATCH] [ja] Translate 06.3.md into Japanese. --- ja/ebook/06.3.md | 137 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 ja/ebook/06.3.md diff --git a/ja/ebook/06.3.md b/ja/ebook/06.3.md new file mode 100644 index 00000000..f6a9d400 --- /dev/null +++ b/ja/ebook/06.3.md @@ -0,0 +1,137 @@ +# 6.3 sessionストレージ +上の節でSessionマネージャの実装原理をご紹介しました。sessionを保存するインターフェースを定義したので、この節ではメモリに基づくsessionストレージインターフェースの実装例をご説明します。その他の保存方法についてはご自身で例を参考に実装してみてください。メモリの実装については下のコード例をご覧ください。 + + package memory + + import ( + "container/list" + "github.com/astaxie/session" + "sync" + "time" + ) + + var pder = &Provider{list: list.New()} + + type SessionStore struct { + sid string //session idユニークID + timeAccessed time.Time //最終アクセス時間 + value map[interface{}]interface{} //sessionに保存される値 + } + + func (st *SessionStore) Set(key, value interface{}) error { + st.value[key] = value + pder.SessionUpdate(st.sid) + return nil + } + + func (st *SessionStore) Get(key interface{}) interface{} { + pder.SessionUpdate(st.sid) + if v, ok := st.value[key]; ok { + return v + } else { + return nil + } + return nil + } + + func (st *SessionStore) Delete(key interface{}) error { + delete(st.value, key) + pder.SessionUpdate(st.sid) + return nil + } + + func (st *SessionStore) SessionID() string { + return st.sid + } + + type Provider struct { + lock sync.Mutex //ロックに使用します + sessions map[string]*list.Element //メモリに保存するために使用します + list *list.List //gcを行うために使用します + } + + func (pder *Provider) SessionInit(sid string) (session.Session, error) { + pder.lock.Lock() + defer pder.lock.Unlock() + v := make(map[interface{}]interface{}, 0) + newsess := &SessionStore{sid: sid, timeAccessed: time.Now(), value: v} + element := pder.list.PushBack(newsess) + pder.sessions[sid] = element + return newsess, nil + } + + func (pder *Provider) SessionRead(sid string) (session.Session, error) { + if element, ok := pder.sessions[sid]; ok { + return element.Value.(*SessionStore), nil + } else { + sess, err := pder.SessionInit(sid) + return sess, err + } + return nil, nil + } + + func (pder *Provider) SessionDestroy(sid string) error { + if element, ok := pder.sessions[sid]; ok { + delete(pder.sessions, sid) + pder.list.Remove(element) + return nil + } + return nil + } + + func (pder *Provider) SessionGC(maxlifetime int64) { + pder.lock.Lock() + defer pder.lock.Unlock() + + for { + element := pder.list.Back() + if element == nil { + break + } + if (element.Value.(*SessionStore).timeAccessed.Unix() + maxlifetime) < time.Now().Unix() { + pder.list.Remove(element) + delete(pder.sessions, element.Value.(*SessionStore).sid) + } else { + break + } + } + } + + func (pder *Provider) SessionUpdate(sid string) error { + pder.lock.Lock() + defer pder.lock.Unlock() + if element, ok := pder.sessions[sid]; ok { + element.Value.(*SessionStore).timeAccessed = time.Now() + pder.list.MoveToFront(element) + return nil + } + return nil + } + + func init() { + pder.sessions = make(map[string]*list.Element, 0) + session.Register("memory", pder) + } + +上のコードはメモリに保存するsessionメカニズムを実現しています。init関数を通じてsessionマネージャに登録されます。このように簡単にコールすることができます。どのようにこのエンジンをコールするのでしょうか?下のコードをご覧ください。 + + import ( + "github.com/astaxie/session" + _ "github.com/astaxie/session/providers/memory" + ) + +importを行う際、memory関数ではinit関数がすでに実行されています。これによりすでにsessionマネージャへの登録が済んでいますので、使用することができます。下の方法によってsessionマネージャを初期化することができます: + + var globalSessions *session.Manager + + //この後、init関数で初期化を行います。 + func init() { + globalSessions, _ = session.NewManager("memory", "gosessionid", 3600) + go globalSessions.GC() + } + + +## links + * [目次]() + * 前へ: [Goはどのようにしてsessionを使用するか](<06.2.md>) + * 次へ: [sessionハイジャックの予防](<06.4.md>)