Mercurial > gemma
view auth/persistent.go @ 196:b67208d82543
Make test output more comprehensive
Running all tests in one transaction ensures the final output tells
about any failing test, not just in the last transaction (i.e.
test script).
The price is that no traces of the tests are left in the database
because we have to rollback in order to have no left-over test roles
in the cluster.
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Fri, 20 Jul 2018 18:31:45 +0200 |
parents | 1585c334e8a7 |
children | e85413e5befa |
line wrap: on
line source
package auth import ( "bytes" "database/sql" "log" "time" bolt "github.com/coreos/bbolt" ) type PersistentConnectionPool struct { db *bolt.DB conns map[string]*Connection cmds chan func(*PersistentConnectionPool) } var sessionsBucket = []byte("sessions") func NewPersistentConnectionPool(filename string) (*PersistentConnectionPool, error) { db, err := bolt.Open(filename, 0600, nil) if err != nil { return nil, err } conns := make(map[string]*Connection) err = db.Update(func(tx *bolt.Tx) error { b, err := tx.CreateBucketIfNotExists(sessionsBucket) if err != nil { return err } // pre-load sessions c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { var conn Connection if err := conn.unserialize(bytes.NewReader(v)); err != nil { return err } conns[string(k)] = &conn } return nil }) if err != nil { db.Close() return nil, err } pcp := &PersistentConnectionPool{ db: db, conns: conns, cmds: make(chan func(*PersistentConnectionPool)), } go pcp.run() return pcp, nil } func (pcp *PersistentConnectionPool) run() { for { select { case cmd := <-pcp.cmds: cmd(pcp) case <-time.After(time.Minute): pcp.cleanDB() case <-time.After(time.Minute * 5): pcp.cleanToken() } } } func (pcp *PersistentConnectionPool) cleanDB() { log.Println("cleanDB: Not implemented, yet.") } func (pcp *PersistentConnectionPool) cleanToken() { log.Println("cleanToken: Not implemented, yet.") } func (pcp *PersistentConnectionPool) Delete(token string) bool { res := make(chan bool) pcp.cmds <- func(pcp *PersistentConnectionPool) { conn, found := pcp.conns[token] if !found { res <- false return } conn.close() delete(pcp.conns, token) err := pcp.db.Update(func(tx *bolt.Tx) error { b := tx.Bucket(sessionsBucket) return b.Delete([]byte(token)) }) if err != nil { log.Printf("error: %v\n", err) } res <- true } return <-res } func (pcp *PersistentConnectionPool) Add(token string, session *Session) *Connection { log.Println("Add: Not implemented, yet.") return nil } func (pcp *PersistentConnectionPool) Renew(token string) (string, error) { log.Println("Renew: Not implemented, yet.") return "", nil } func (pcp *PersistentConnectionPool) Do(token string, fn func(*sql.DB) error) error { log.Println("Do: Not implemented, yet.") return nil } func (pcp *PersistentConnectionPool) Session(token string) *Session { log.Println("Session: Not implemented, yet.") return nil } func (pcp *PersistentConnectionPool) Shutdown() error { log.Println("info: shutdown persistent connection pool.") if db := pcp.db; db != nil { pcp.db = nil return db.Close() } return nil }