annotate auth/connection.go @ 129:ee5a3dd8e972

Forgot to check if a db connection is already close when closing idle db connections.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 28 Jun 2018 16:45:01 +0200
parents 44794c641277
children 13b82701b1fb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
26
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
1 package auth
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
2
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
3 import (
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
4 "database/sql"
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
5 "errors"
126
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
6 "log"
26
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
7 "time"
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
8 )
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
9
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
10 var ErrNoSuchToken = errors.New("No such token")
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
11
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
12 var ConnPool = NewConnectionPool()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
13
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
14 const (
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
15 maxOpen = 16
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
16 maxDBIdle = time.Minute * 5
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
17 maxTokenIdle = time.Minute * 20
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
18 )
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
19
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
20 type Connection struct {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
21 user string
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
22 password string
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
23
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
24 access time.Time
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
25 db *sql.DB
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
26 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
27
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
28 func (c *Connection) set(user, password string) {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
29 c.user = user
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
30 c.password = password
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
31 c.access = time.Now()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
32 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
33
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
34 type ConnectionPool struct {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
35 conns map[string]*Connection
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
36 cmds chan func(*ConnectionPool)
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
37 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
38
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
39 func NewConnectionPool() *ConnectionPool {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
40 cp := &ConnectionPool{
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
41 conns: make(map[string]*Connection),
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
42 cmds: make(chan func(*ConnectionPool)),
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
43 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
44 go cp.run()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
45 return cp
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
46 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
47
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
48 func (cp *ConnectionPool) run() {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
49 for {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
50 select {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
51 case cmd := <-cp.cmds:
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
52 cmd(cp)
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
53 case <-time.After(time.Minute):
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
54 cp.cleanDB()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
55 case <-time.After(time.Minute * 5):
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
56 cp.cleanToken()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
57 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
58 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
59 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
60
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
61 func (cp *ConnectionPool) cleanDB() {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
62 valid := time.Now().Add(-maxDBIdle)
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
63 for _, con := range cp.conns {
129
ee5a3dd8e972 Forgot to check if a db connection is already close when closing idle db connections.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 127
diff changeset
64 if con.access.Before(valid) && con.db != nil {
26
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
65 con.db.Close()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
66 con.db = nil
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
67 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
68 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
69 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
70
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
71 func (cp *ConnectionPool) cleanToken() {
27
c3e2cd7fa46f Fixed wrong idle time for tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 26
diff changeset
72 valid := time.Now().Add(-maxTokenIdle)
26
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
73 for token, con := range cp.conns {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
74 if con.access.Before(valid) {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
75 if con.db != nil {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
76 // TODO: Be more graceful here?
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
77 con.db.Close()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
78 con.db = nil
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
79 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
80 delete(cp.conns, token)
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
81 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
82 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
83 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
84
126
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
85 func (cp *ConnectionPool) Delete(token string) bool {
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
86 res := make(chan bool)
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
87 cp.cmds <- func(cp *ConnectionPool) {
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
88 conn, found := cp.conns[token]
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
89 if !found {
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
90 res <- false
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
91 return
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
92 }
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
93 delete(cp.conns, token)
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
94 if conn.db != nil {
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
95 if err := conn.db.Close(); err != nil {
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
96 log.Printf("warn: %v\n", err)
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
97 }
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
98 conn.db = nil
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
99 }
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
100 res <- true
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
101 }
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
102 return <-res
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
103 }
89cf2e7672ff Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 27
diff changeset
104
127
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
105 func (cp *ConnectionPool) Replace(
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
106 token string,
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
107 replace func(string, string) (string, error)) (string, error) {
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
108
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
109 type res struct {
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
110 token string
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
111 err error
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
112 }
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
113
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
114 resCh := make(chan res)
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
115
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
116 cp.cmds <- func(cp *ConnectionPool) {
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
117 conn, found := cp.conns[token]
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
118 if !found {
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
119 resCh <- res{err: ErrNoSuchToken}
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
120 return
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
121 }
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
122 newToken, err := replace(conn.user, conn.password)
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
123 if err == nil {
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
124 delete(cp.conns, token)
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
125 cp.conns[newToken] = conn
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
126 }
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
127 resCh <- res{token: newToken, err: err}
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
128 }
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
129
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
130 r := <-resCh
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
131 return r.token, r.err
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
132 }
44794c641277 Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 126
diff changeset
133
26
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
134 func (cp *ConnectionPool) Add(token, user, password string) *Connection {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
135 res := make(chan *Connection)
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
136
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
137 cp.cmds <- func(cp *ConnectionPool) {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
138
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
139 con := cp.conns[token]
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
140 if con == nil {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
141 con = &Connection{}
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
142 cp.conns[token] = con
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
143 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
144 con.set(user, password)
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
145 res <- con
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
146 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
147
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
148 con := <-res
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
149 return con
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
150 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
151
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
152 func trim(cp *ConnectionPool) {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
153
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
154 least := time.Now()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
155 var count int
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
156 var oldest *Connection
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
157
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
158 for _, con := range cp.conns {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
159 if con.db != nil {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
160 if con.access.Before(least) {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
161 least = con.access
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
162 oldest = con
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
163 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
164 count++
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
165 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
166 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
167 if count > maxOpen {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
168 oldest.db.Close()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
169 oldest.db = nil
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
170 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
171 return
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
172 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
173
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
174 func (cp *ConnectionPool) Do(token string, fn func(*sql.DB) error) error {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
175
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
176 type result struct {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
177 con *Connection
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
178 err error
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
179 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
180
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
181 res := make(chan result)
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
182
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
183 cp.cmds <- func(cp *ConnectionPool) {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
184 con := cp.conns[token]
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
185 if con == nil {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
186 res <- result{err: ErrNoSuchToken}
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
187 return
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
188 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
189 con.access = time.Now()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
190 if con.db != nil {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
191 res <- result{con: con}
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
192 return
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
193 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
194
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
195 db, err := opendb(con.user, con.password)
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
196 if err != nil {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
197 res <- result{err: err}
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
198 return
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
199 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
200 con.db = db
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
201 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
202
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
203 r := <-res
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
204
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
205 if r.err != nil {
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
206 return r.err
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
207 }
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
208
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
209 defer func() { cp.cmds <- trim }()
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
210
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
211 return fn(r.con.db)
96a429c5f227 Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
212 }