Mercurial > gemma
annotate auth/connection.go @ 133:f4523620ba5d
Close idle connections until there are only maxOpen connections open.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 28 Jun 2018 17:26:38 +0200 |
parents | 61f86d069259 |
children | 0c56c56a1c44 |
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 ( |
130
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
15 maxOpen = 16 |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
16 maxDBIdle = time.Minute * 5 |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
17 ) |
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 type Connection struct { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
20 user string |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
21 password string |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
22 |
131
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
23 access time.Time |
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
24 db *sql.DB |
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
25 refCount int |
26
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 |
130
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
34 func (c *Connection) close() { |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
35 if c.db != nil { |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
36 if err := c.db.Close(); err != nil { |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
37 log.Printf("warn: %v\n", err) |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
38 } |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
39 c.db = nil |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
40 } |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
41 } |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
42 |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
43 type ConnectionPool struct { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
44 conns map[string]*Connection |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
45 cmds chan func(*ConnectionPool) |
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 NewConnectionPool() *ConnectionPool { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
49 cp := &ConnectionPool{ |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
50 conns: make(map[string]*Connection), |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
51 cmds: make(chan func(*ConnectionPool)), |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
52 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
53 go cp.run() |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
54 return cp |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
55 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
56 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
57 func (cp *ConnectionPool) run() { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
58 for { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
59 select { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
60 case cmd := <-cp.cmds: |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
61 cmd(cp) |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
62 case <-time.After(time.Minute): |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
63 cp.cleanDB() |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
64 case <-time.After(time.Minute * 5): |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
65 cp.cleanToken() |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
66 } |
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 func (cp *ConnectionPool) cleanDB() { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
71 valid := time.Now().Add(-maxDBIdle) |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
72 for _, con := range cp.conns { |
132
61f86d069259
Dont close db connections if they are currently busy when garbage collecting idle db connections.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
131
diff
changeset
|
73 if con.refCount <= 0 && con.access.Before(valid) { |
61f86d069259
Dont close db connections if they are currently busy when garbage collecting idle db connections.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
131
diff
changeset
|
74 con.close() |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
75 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
76 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
77 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
78 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
79 func (cp *ConnectionPool) cleanToken() { |
130
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
80 now := time.Now() |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
81 for token, con := range cp.conns { |
130
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
82 claims, err := TokenToClaims(token) |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
83 if err != nil { // Should not happen. |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
84 log.Printf("error: %v\n", err) |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
85 con.close() |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
86 delete(cp.conns, token) |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
87 continue |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
88 } |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
89 expires := time.Unix(claims.ExpiresAt, 0) |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
90 if expires.Before(now) { |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
91 // TODO: Be more graceful here? |
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
92 con.close() |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
93 delete(cp.conns, token) |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
94 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
95 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
96 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
97 |
126
89cf2e7672ff
Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
27
diff
changeset
|
98 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
|
99 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
|
100 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
|
101 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
|
102 if !found { |
89cf2e7672ff
Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
27
diff
changeset
|
103 res <- false |
89cf2e7672ff
Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
27
diff
changeset
|
104 return |
89cf2e7672ff
Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
27
diff
changeset
|
105 } |
130
13b82701b1fb
Take expiring time from serialized tokens to garbage collect them.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
129
diff
changeset
|
106 conn.close() |
126
89cf2e7672ff
Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
27
diff
changeset
|
107 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
|
108 res <- true |
89cf2e7672ff
Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
27
diff
changeset
|
109 } |
89cf2e7672ff
Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
27
diff
changeset
|
110 return <-res |
89cf2e7672ff
Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
27
diff
changeset
|
111 } |
89cf2e7672ff
Implemented an explicit token deletion under endpoint /api/logout.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
27
diff
changeset
|
112 |
127
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
113 func (cp *ConnectionPool) Replace( |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
114 token string, |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
115 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
|
116 |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
117 type res struct { |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
118 token string |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
119 err error |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
120 } |
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 resCh := make(chan res) |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
123 |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
124 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
|
125 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
|
126 if !found { |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
127 resCh <- res{err: ErrNoSuchToken} |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
128 return |
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 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
|
131 if err == nil { |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
132 delete(cp.conns, token) |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
133 cp.conns[newToken] = conn |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
134 } |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
135 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
|
136 } |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
137 |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
138 r := <-resCh |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
139 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
|
140 } |
44794c641277
Implemented explicit token renewal under endpoint /api/renew.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
126
diff
changeset
|
141 |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
142 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
|
143 res := make(chan *Connection) |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
144 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
145 cp.cmds <- func(cp *ConnectionPool) { |
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 con := cp.conns[token] |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
148 if con == nil { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
149 con = &Connection{} |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
150 cp.conns[token] = con |
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 con.set(user, password) |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
153 res <- con |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
154 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
155 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
156 con := <-res |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
157 return con |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
158 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
159 |
131
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
160 func (cp *ConnectionPool) trim(conn *Connection) { |
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
161 |
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
162 conn.refCount-- |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
163 |
133
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
164 for { |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
165 least := time.Now() |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
166 var count int |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
167 var oldest *Connection |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
168 |
133
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
169 for _, con := range cp.conns { |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
170 if con.db != nil && con.refCount <= 0 { |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
171 if con.access.Before(least) { |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
172 least = con.access |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
173 oldest = con |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
174 } |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
175 count++ |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
176 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
177 } |
133
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
178 if count <= maxOpen { |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
179 break |
f4523620ba5d
Close idle connections until there are only maxOpen connections open.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
132
diff
changeset
|
180 } |
131
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
181 oldest.close() |
26
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 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
184 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
185 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
|
186 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
187 type result struct { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
188 con *Connection |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
189 err error |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
190 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
191 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
192 res := make(chan result) |
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 cp.cmds <- func(cp *ConnectionPool) { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
195 con := cp.conns[token] |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
196 if con == nil { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
197 res <- result{err: ErrNoSuchToken} |
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.access = time.Now() |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
201 if con.db != nil { |
131
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
202 con.refCount++ |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
203 res <- result{con: con} |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
204 return |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
205 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
206 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
207 db, err := opendb(con.user, con.password) |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
208 if err != nil { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
209 res <- result{err: err} |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
210 return |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
211 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
212 con.db = db |
131
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
213 con.refCount++ |
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
214 res <- result{con: con} |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
215 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
216 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
217 r := <-res |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
218 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
219 if r.err != nil { |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
220 return r.err |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
221 } |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
222 |
131
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
223 defer func() { |
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
224 cp.cmds <- func(cp *ConnectionPool) { |
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
225 cp.trim(r.con) |
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
226 } |
af114cf64822
Added some reference counting to open db connection to not forcefully close them when system is under pressure. TODO: check if this race free (it should).
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
130
diff
changeset
|
227 }() |
26
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
228 |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
229 return fn(r.con.db) |
96a429c5f227
Fundamental connection pool based on tokens.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
230 } |