|
3 | 3 | (require (for-syntax racket/base |
4 | 4 | syntax/parse/pre) |
5 | 5 | component |
| 6 | + data/pool |
6 | 7 | db |
7 | 8 | (only-in db/private/generic/interfaces |
8 | 9 | connection<%> |
|
24 | 25 | (->* [(-> connection?)] |
25 | 26 | [#:log-statements? boolean? |
26 | 27 | #:max-connections exact-positive-integer? |
| 28 | + #:connection-idle-ttl (or/c +inf.0 exact-positive-integer?) |
27 | 29 | #:max-idle-connections exact-positive-integer?] |
28 | 30 | (-> database?))] |
29 | 31 | [call-with-database-connection |
|
46 | 48 | (connection-pool |
47 | 49 | connector ;; noqa |
48 | 50 | max-connections ;; noqa |
49 | | - max-idle-connections ;; noqa |
| 51 | + connection-idle-ttl ;; noqa |
50 | 52 | log-statements?) |
51 | 53 | #:methods gen:component |
52 | 54 | [(define (component-start db) ;; noqa |
53 | | - (match-define (database _ connector max-conns max-idle-conns _log?) |
54 | | - db) |
| 55 | + (match-define (database _ connector max-size idle-ttl _) db) |
55 | 56 | (define pool |
56 | | - (connection-pool |
57 | | - #:max-connections max-conns |
58 | | - #:max-idle-connections max-idle-conns |
59 | | - connector)) |
| 57 | + (make-pool |
| 58 | + #:max-size max-size |
| 59 | + #:idle-ttl idle-ttl |
| 60 | + (lambda () |
| 61 | + ;; This procedure must not raise an exception. So, on connect failure, return |
| 62 | + ;; a dummy object whose connected? method re-raises the exception. This makes |
| 63 | + ;; database-borrow-connection raise at the appropriate time. |
| 64 | + (with-handlers ([exn:fail? (λ (e) (new dummy-connection% [p pool] [e e]))]) |
| 65 | + (connector))) |
| 66 | + disconnect)) |
60 | 67 | (struct-copy database db [connection-pool pool])) |
61 | 68 |
|
62 | 69 | (define (component-stop db) ;; noqa |
63 | | - (send (database-connection-pool db) clear-idle) |
| 70 | + (pool-close! (database-connection-pool db)) |
64 | 71 | (struct-copy database db [connection-pool #f]))]) |
65 | 72 |
|
66 | 73 | (define ((make-database-factory connector |
67 | 74 | #:log-statements? [log-statements? #f] |
68 | 75 | #:max-connections [max-connections 16] |
69 | | - #:max-idle-connections [max-idle-connections 2])) |
| 76 | + #:connection-idle-ttl [connection-idle-ttl (* 60 1000)] |
| 77 | + #:max-idle-connections [_max-idle-connections 2])) |
70 | 78 | (database |
71 | 79 | #;connection-pool #f |
72 | 80 | #;connector connector |
73 | 81 | #;max-connections max-connections |
74 | | - #;max-idle-connections max-idle-connections |
| 82 | + #;connection-idle-ttl connection-idle-ttl |
75 | 83 | #;log-statements log-statements?)) |
76 | 84 |
|
77 | 85 | (define current-database-connection |
|
90 | 98 | (set! conn the-conn) |
91 | 99 | (set! close void))] |
92 | 100 | [else |
93 | | - (define the-conn |
94 | | - (connection-pool-lease |
95 | | - (database-connection-pool db))) |
| 101 | + (define the-conn (database-borrow-connection db)) |
96 | 102 | (set! conn the-conn) |
97 | | - (set! close (λ () (disconnect the-conn)))]))) |
| 103 | + (set! close (λ () (database-release-connection db the-conn)))]))) |
98 | 104 | (lambda () |
99 | 105 | (with-timing "proc" |
100 | 106 | (parameterize ([current-database-connection conn]) |
|
114 | 120 | (proc conn)))))) |
115 | 121 |
|
116 | 122 | (define (database-borrow-connection db) |
117 | | - (connection-pool-lease |
118 | | - (database-connection-pool db))) |
| 123 | + (define the-pool |
| 124 | + (database-connection-pool db)) |
| 125 | + (define the-conn |
| 126 | + (pool-take! the-pool)) |
| 127 | + (cond |
| 128 | + [(send the-conn connected?) |
| 129 | + the-conn] |
| 130 | + [else |
| 131 | + (pool-abandon! the-pool the-conn) |
| 132 | + (database-borrow-connection db)])) |
119 | 133 |
|
120 | | -(define (database-release-connection _db conn) |
121 | | - (disconnect conn)) |
| 134 | +(define (database-release-connection db conn) |
| 135 | + (pool-release! (database-connection-pool db) conn)) |
122 | 136 |
|
123 | 137 | (define-syntax (with-database-connection stx) |
124 | 138 | (syntax-parse stx |
|
140 | 154 | (lambda (name) |
141 | 155 | e ...))])) |
142 | 156 |
|
| 157 | +(define dummy-connection% |
| 158 | + (class* object% (connection<%>) |
| 159 | + (init-field p e) |
| 160 | + (super-new) |
| 161 | + |
| 162 | + (define-syntax-rule (define-dummies [id arg ...] ...) |
| 163 | + (begin |
| 164 | + (define/public (id arg ...) |
| 165 | + (unless abandoned? |
| 166 | + (set! abandoned? #t) |
| 167 | + (pool-abandon! p this)) |
| 168 | + (raise e)) ...)) |
| 169 | + |
| 170 | + (define abandoned? #f) |
| 171 | + |
| 172 | + (define-dummies |
| 173 | + [connected?] |
| 174 | + [get-dbsystem] |
| 175 | + [query fsym stmt cursor?] |
| 176 | + [prepare fsym stmt close-on-exec?] |
| 177 | + [fetch/cursor fsym cursor fetch-size] |
| 178 | + [get-base] |
| 179 | + [list-tables fsym schema] |
| 180 | + [start-transaction fsym isolation option cwt?] |
| 181 | + [end-transaction fsym mode cwt?] |
| 182 | + [transaction-status fsym] |
| 183 | + [free-statement pst need-lock?]) |
| 184 | + |
| 185 | + (define/public (disconnect) |
| 186 | + (void)))) |
| 187 | + |
143 | 188 |
|
144 | 189 | ;; Query Logging ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
145 | 190 |
|
|
0 commit comments