Mercurial > gemma
annotate auth/inmemory.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 | 3349bfc2a047 |
children |
rev | line source |
---|---|
148
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
1 package auth |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
2 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
3 import ( |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
4 "database/sql" |
151
3349bfc2a047
Shutdown server gracefully.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
148
diff
changeset
|
5 "log" |
148
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
6 "time" |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
7 ) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
8 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
9 type InMemoryConnectionPool struct { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
10 conns map[string]*Connection |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
11 cmds chan func(*InMemoryConnectionPool) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
12 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
13 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
14 func NewInMemoryConnectionPool() *InMemoryConnectionPool { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
15 cp := &InMemoryConnectionPool{ |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
16 conns: make(map[string]*Connection), |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
17 cmds: make(chan func(*InMemoryConnectionPool)), |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
18 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
19 go cp.run() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
20 return cp |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
21 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
22 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
23 func (cp *InMemoryConnectionPool) run() { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
24 for { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
25 select { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
26 case cmd := <-cp.cmds: |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
27 cmd(cp) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
28 case <-time.After(time.Minute): |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
29 cp.cleanDB() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
30 case <-time.After(time.Minute * 5): |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
31 cp.cleanToken() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
32 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
33 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
34 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
35 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
36 func (cp *InMemoryConnectionPool) cleanDB() { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
37 valid := time.Now().Add(-maxDBIdle) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
38 for _, con := range cp.conns { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
39 if con.refCount <= 0 && con.last().Before(valid) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
40 con.close() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
41 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
42 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
43 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
44 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
45 func (cp *InMemoryConnectionPool) cleanToken() { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
46 now := time.Now() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
47 for token, con := range cp.conns { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
48 expires := time.Unix(con.session.ExpiresAt, 0) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
49 if expires.Before(now) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
50 // TODO: Be more graceful here? |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
51 con.close() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
52 delete(cp.conns, token) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
53 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
54 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
55 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
56 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
57 func (cp *InMemoryConnectionPool) Delete(token string) bool { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
58 res := make(chan bool) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
59 cp.cmds <- func(cp *InMemoryConnectionPool) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
60 conn, found := cp.conns[token] |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
61 if !found { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
62 res <- false |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
63 return |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
64 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
65 conn.close() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
66 delete(cp.conns, token) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
67 res <- true |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
68 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
69 return <-res |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
70 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
71 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
72 func (cp *InMemoryConnectionPool) Add(token string, session *Session) *Connection { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
73 res := make(chan *Connection) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
74 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
75 cp.cmds <- func(cp *InMemoryConnectionPool) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
76 con := cp.conns[token] |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
77 if con == nil { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
78 con = &Connection{} |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
79 cp.conns[token] = con |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
80 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
81 con.set(session) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
82 res <- con |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
83 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
84 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
85 con := <-res |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
86 return con |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
87 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
88 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
89 func (cp *InMemoryConnectionPool) Renew(token string) (string, error) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
90 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
91 type result struct { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
92 newToken string |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
93 err error |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
94 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
95 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
96 resCh := make(chan result) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
97 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
98 cp.cmds <- func(cp *InMemoryConnectionPool) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
99 con := cp.conns[token] |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
100 if con == nil { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
101 resCh <- result{err: ErrNoSuchToken} |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
102 } else { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
103 delete(cp.conns, token) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
104 newToken := GenerateSessionKey() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
105 // TODO: Ensure that this is not racy! |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
106 con.session.ExpiresAt = time.Now().Add(maxTokenValid).Unix() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
107 cp.conns[newToken] = con |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
108 resCh <- result{newToken: newToken} |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
109 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
110 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
111 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
112 r := <-resCh |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
113 return r.newToken, r.err |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
114 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
115 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
116 func (cp *InMemoryConnectionPool) trim(conn *Connection) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
117 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
118 conn.refCount-- |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
119 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
120 for { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
121 least := time.Now() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
122 var count int |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
123 var oldest *Connection |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
124 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
125 for _, con := range cp.conns { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
126 if con.db != nil && con.refCount <= 0 { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
127 if last := con.last(); last.Before(least) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
128 least = last |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
129 oldest = con |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
130 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
131 count++ |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
132 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
133 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
134 if count <= maxOpen { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
135 break |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
136 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
137 oldest.close() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
138 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
139 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
140 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
141 func (cp *InMemoryConnectionPool) Do(token string, fn func(*sql.DB) error) error { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
142 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
143 type result struct { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
144 con *Connection |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
145 err error |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
146 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
147 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
148 res := make(chan result) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
149 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
150 cp.cmds <- func(cp *InMemoryConnectionPool) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
151 con := cp.conns[token] |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
152 if con == nil { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
153 res <- result{err: ErrNoSuchToken} |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
154 return |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
155 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
156 con.touch() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
157 if con.db != nil { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
158 con.refCount++ |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
159 res <- result{con: con} |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
160 return |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
161 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
162 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
163 session := con.session |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
164 db, err := opendb(session.User, session.Password) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
165 if err != nil { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
166 res <- result{err: err} |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
167 return |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
168 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
169 con.db = db |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
170 con.refCount++ |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
171 res <- result{con: con} |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
172 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
173 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
174 r := <-res |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
175 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
176 if r.err != nil { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
177 return r.err |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
178 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
179 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
180 defer func() { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
181 cp.cmds <- func(cp *InMemoryConnectionPool) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
182 cp.trim(r.con) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
183 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
184 }() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
185 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
186 return fn(r.con.db) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
187 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
188 |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
189 func (cp *InMemoryConnectionPool) Session(token string) *Session { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
190 res := make(chan *Session) |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
191 cp.cmds <- func(cp *InMemoryConnectionPool) { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
192 con := cp.conns[token] |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
193 if con == nil { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
194 res <- nil |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
195 } else { |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
196 con.touch() |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
197 res <- con.session |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
198 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
199 } |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
200 return <-res |
0116aae1071b
Made ConnectionPool an interface and use current in-memory implementation.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff
changeset
|
201 } |
151
3349bfc2a047
Shutdown server gracefully.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
148
diff
changeset
|
202 |
3349bfc2a047
Shutdown server gracefully.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
148
diff
changeset
|
203 func (cp *InMemoryConnectionPool) Shutdown() error { |
3349bfc2a047
Shutdown server gracefully.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
148
diff
changeset
|
204 log.Println("info: shutdown in-memory connection pool.") |
3349bfc2a047
Shutdown server gracefully.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
148
diff
changeset
|
205 return nil |
3349bfc2a047
Shutdown server gracefully.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
148
diff
changeset
|
206 } |