1
1
var mysql = require ( '../index.js' ) ;
2
2
3
3
var EventEmitter = require ( 'events' ) . EventEmitter ;
4
+ var Timers = require ( 'timers' ) ;
4
5
var Util = require ( 'util' ) ;
5
6
var PoolConnection = require ( './pool_connection.js' ) ;
6
7
var Queue = require ( 'denque' ) ;
@@ -18,6 +19,14 @@ function Pool(options) {
18
19
this . _freeConnections = new Queue ( ) ;
19
20
this . _connectionQueue = new Queue ( ) ;
20
21
this . _closed = false ;
22
+ if ( this . config . autoOpenConnections ) {
23
+ var self = this ;
24
+ for ( var i = 0 ; i < this . config . minConnections ; i ++ ) {
25
+ this . getConnection ( function ( conn ) {
26
+ self . releaseConnection ( conn ) ;
27
+ } )
28
+ }
29
+ }
21
30
}
22
31
23
32
Pool . prototype . getConnection = function ( cb ) {
@@ -82,6 +91,7 @@ Pool.prototype.getConnection = function(cb) {
82
91
Pool . prototype . releaseConnection = function ( connection ) {
83
92
var cb ;
84
93
94
+ connection . _lastReleased = Date . now ( ) ;
85
95
if ( ! connection . _pool ) {
86
96
// The connection has been removed from the pool and is no longer good.
87
97
if ( this . _connectionQueue . length ) {
@@ -95,6 +105,7 @@ Pool.prototype.releaseConnection = function(connection) {
95
105
process . nextTick ( cb . bind ( null , null , connection ) ) ;
96
106
} else {
97
107
this . _freeConnections . push ( connection ) ;
108
+ this . _manageExpiredTimer ( ) ;
98
109
}
99
110
} ;
100
111
@@ -111,14 +122,14 @@ Pool.prototype.end = function(cb) {
111
122
112
123
var calledBack = false ;
113
124
var closedConnections = 0 ;
114
- var connection ;
125
+ var numConnections = this . _allConnections . length ;
115
126
116
127
var endCB = function ( err ) {
117
128
if ( calledBack ) {
118
129
return ;
119
130
}
120
131
121
- if ( err || ++ closedConnections >= this . _allConnections . length ) {
132
+ if ( err || ++ closedConnections >= numConnections ) {
122
133
calledBack = true ;
123
134
cb ( err ) ;
124
135
return ;
@@ -130,9 +141,9 @@ Pool.prototype.end = function(cb) {
130
141
return ;
131
142
}
132
143
133
- for ( var i = 0 ; i < this . _allConnections . length ; i ++ ) {
134
- connection = this . _allConnections . get ( i ) ;
135
- connection . _realEnd ( endCB ) ;
144
+ var connection ;
145
+ while ( ( connection = this . _allConnections . shift ( ) ) ) {
146
+ this . _closeConnection ( connection , endCB ) ;
136
147
}
137
148
} ;
138
149
@@ -184,14 +195,56 @@ Pool.prototype.execute = function(sql, values, cb) {
184
195
} ) ;
185
196
} ;
186
197
198
+ Pool . prototype . _manageExpiredTimer = function ( ) {
199
+ var hasExtra = this . _allConnections . length > this . config . minConnections ;
200
+ if ( hasExtra && ! this . _expiredTimer ) {
201
+ this . _expiredTimer = Timers . setInterval (
202
+ Pool . prototype . _closeIdleConnections . bind ( this ) ,
203
+ Math . min ( 15 , this . config . idleTimeout ) * 1000
204
+ ) ;
205
+ } else if ( ! hasExtra && this . _expiredTimer ) {
206
+ Timers . clearInterval ( this . _expiredTimer ) ;
207
+ this . _expiredTimer = null ;
208
+ }
209
+ } ;
210
+
211
+ Pool . prototype . _closeIdleConnections = function ( ) {
212
+ var now = Date . now ( ) ;
213
+ var timeout = this . config . idleTimeout * 1000 ;
214
+ var length = this . _freeConnections . length ;
215
+ var numExtra = this . _allConnections . length - this . config . minConnections ;
216
+ for ( var i = 0 ; numExtra > 0 && i < length ; i ++ ) {
217
+ var conn = this . _freeConnections . get ( i ) ;
218
+
219
+ if ( now > conn . _lastReleased + timeout ) {
220
+ // This connection has been unused for longer than the timeout
221
+ this . _closeConnection ( conn ) ;
222
+ // decrement i and length as the length will be reduced by 1 by closeConnection
223
+ i -- ;
224
+ length -- ;
225
+ numExtra -- ;
226
+ }
227
+ }
228
+ this . _manageExpiredTimer ( ) ;
229
+ } ;
230
+
187
231
Pool . prototype . _removeConnection = function ( connection ) {
188
232
// Remove connection from all connections
189
233
spliceConnection ( this . _allConnections , connection ) ;
190
234
191
235
// Remove connection from free connections
192
236
spliceConnection ( this . _freeConnections , connection ) ;
193
237
194
- this . releaseConnection ( connection ) ;
238
+ if ( ! connection . _closing && ! connection . _closed ) {
239
+ this . releaseConnection ( connection ) ;
240
+ }
241
+
242
+ this . _manageExpiredTimer ( ) ;
243
+ } ;
244
+
245
+ Pool . prototype . _closeConnection = function ( connection , cb ) {
246
+ connection . _realEnd ( cb ) ;
247
+ this . _removeConnection ( connection ) ;
195
248
} ;
196
249
197
250
Pool . prototype . format = function ( sql , values ) {
0 commit comments