comparison auth/persistent.go @ 193:1585c334e8a7

More on persisting sessions.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 20 Jul 2018 18:32:11 +0200
parents 3457a60fb12d
children e85413e5befa
comparison
equal deleted inserted replaced
190:3457a60fb12d 193:1585c334e8a7
1 package auth 1 package auth
2 2
3 import ( 3 import (
4 "bytes"
4 "database/sql" 5 "database/sql"
5 "log" 6 "log"
7 "time"
8
9 bolt "github.com/coreos/bbolt"
6 ) 10 )
7 11
8 type PersistentConnectionPool struct { 12 type PersistentConnectionPool struct {
9 filename string 13 db *bolt.DB
14 conns map[string]*Connection
15 cmds chan func(*PersistentConnectionPool)
10 } 16 }
17
18 var sessionsBucket = []byte("sessions")
11 19
12 func NewPersistentConnectionPool(filename string) (*PersistentConnectionPool, error) { 20 func NewPersistentConnectionPool(filename string) (*PersistentConnectionPool, error) {
13 21
14 log.Println("NewInMemoryConnectionPool: Not implemented, yet.") 22 db, err := bolt.Open(filename, 0600, nil)
23 if err != nil {
24 return nil, err
25 }
26
27 conns := make(map[string]*Connection)
28 err = db.Update(func(tx *bolt.Tx) error {
29 b, err := tx.CreateBucketIfNotExists(sessionsBucket)
30 if err != nil {
31 return err
32 }
33
34 // pre-load sessions
35 c := b.Cursor()
36
37 for k, v := c.First(); k != nil; k, v = c.Next() {
38 var conn Connection
39 if err := conn.unserialize(bytes.NewReader(v)); err != nil {
40 return err
41 }
42 conns[string(k)] = &conn
43 }
44
45 return nil
46 })
47
48 if err != nil {
49 db.Close()
50 return nil, err
51 }
52
15 pcp := &PersistentConnectionPool{ 53 pcp := &PersistentConnectionPool{
16 filename: filename, 54 db: db,
55 conns: conns,
56 cmds: make(chan func(*PersistentConnectionPool)),
17 } 57 }
58 go pcp.run()
18 return pcp, nil 59 return pcp, nil
19 } 60 }
20 61
62 func (pcp *PersistentConnectionPool) run() {
63 for {
64 select {
65 case cmd := <-pcp.cmds:
66 cmd(pcp)
67 case <-time.After(time.Minute):
68 pcp.cleanDB()
69 case <-time.After(time.Minute * 5):
70 pcp.cleanToken()
71 }
72 }
73 }
74
75 func (pcp *PersistentConnectionPool) cleanDB() {
76 log.Println("cleanDB: Not implemented, yet.")
77 }
78
79 func (pcp *PersistentConnectionPool) cleanToken() {
80 log.Println("cleanToken: Not implemented, yet.")
81 }
82
21 func (pcp *PersistentConnectionPool) Delete(token string) bool { 83 func (pcp *PersistentConnectionPool) Delete(token string) bool {
22 log.Println("Delete: Not implemented, yet.") 84 res := make(chan bool)
23 return false 85 pcp.cmds <- func(pcp *PersistentConnectionPool) {
86 conn, found := pcp.conns[token]
87 if !found {
88 res <- false
89 return
90 }
91 conn.close()
92 delete(pcp.conns, token)
93 err := pcp.db.Update(func(tx *bolt.Tx) error {
94 b := tx.Bucket(sessionsBucket)
95 return b.Delete([]byte(token))
96 })
97 if err != nil {
98 log.Printf("error: %v\n", err)
99 }
100 res <- true
101 }
102 return <-res
24 } 103 }
25 104
26 func (pcp *PersistentConnectionPool) Add(token string, session *Session) *Connection { 105 func (pcp *PersistentConnectionPool) Add(token string, session *Session) *Connection {
27 log.Println("Add: Not implemented, yet.") 106 log.Println("Add: Not implemented, yet.")
28 return nil 107 return nil
42 log.Println("Session: Not implemented, yet.") 121 log.Println("Session: Not implemented, yet.")
43 return nil 122 return nil
44 } 123 }
45 124
46 func (pcp *PersistentConnectionPool) Shutdown() error { 125 func (pcp *PersistentConnectionPool) Shutdown() error {
47 log.Println("Shutdown: Not implemented, yet.") 126 log.Println("info: shutdown persistent connection pool.")
127 if db := pcp.db; db != nil {
128 pcp.db = nil
129 return db.Close()
130 }
48 return nil 131 return nil
49 } 132 }