11var mysql = require ( '../index.js' ) ;
22
33var EventEmitter = require ( 'events' ) . EventEmitter ;
4+ var Timers = require ( 'timers' ) ;
45var Util = require ( 'util' ) ;
56var PoolConnection = require ( './pool_connection.js' ) ;
67var Queue = require ( 'denque' ) ;
@@ -18,6 +19,22 @@ function Pool(options) {
1819 this . _freeConnections = new Queue ( ) ;
1920 this . _connectionQueue = new Queue ( ) ;
2021 this . _closed = false ;
22+ if ( this . config . autoOpenConnections ) {
23+ this . _openingConnections = true ;
24+ var self = this ;
25+ var opened = 0 ;
26+ for ( var i = 0 ; i < this . config . minConnections ; i ++ ) {
27+ this . getConnection ( function ( conn ) {
28+ process . nextTick ( function ( ) {
29+ self . releaseConnection ( conn ) ;
30+ if ( ++ opened === self . config . minConnections ) {
31+ self . _openingConnections = false ;
32+ }
33+ } ) ;
34+ } ) ;
35+ }
36+
37+ }
2138}
2239
2340Pool . prototype . getConnection = function ( cb ) {
@@ -26,6 +43,10 @@ Pool.prototype.getConnection = function(cb) {
2643 return cb ( new Error ( 'Pool is closed.' ) ) ;
2744 } ) ;
2845 }
46+ if ( this . _openingConnections ) {
47+ // We are opening a connect, use it when ready
48+ return this . _connectionQueue . push ( cb ) ;
49+ }
2950
3051 var connection ;
3152
@@ -82,6 +103,7 @@ Pool.prototype.getConnection = function(cb) {
82103Pool . prototype . releaseConnection = function ( connection ) {
83104 var cb ;
84105
106+ connection . _lastReleased = Date . now ( ) ;
85107 if ( ! connection . _pool ) {
86108 // The connection has been removed from the pool and is no longer good.
87109 if ( this . _connectionQueue . length ) {
@@ -95,6 +117,7 @@ Pool.prototype.releaseConnection = function(connection) {
95117 process . nextTick ( cb . bind ( null , null , connection ) ) ;
96118 } else {
97119 this . _freeConnections . push ( connection ) ;
120+ this . _manageExpiredTimer ( ) ;
98121 }
99122} ;
100123
@@ -111,14 +134,14 @@ Pool.prototype.end = function(cb) {
111134
112135 var calledBack = false ;
113136 var closedConnections = 0 ;
114- var connection ;
137+ var numConnections = this . _allConnections . length ;
115138
116139 var endCB = function ( err ) {
117140 if ( calledBack ) {
118141 return ;
119142 }
120143
121- if ( err || ++ closedConnections >= this . _allConnections . length ) {
144+ if ( err || ++ closedConnections >= numConnections ) {
122145 calledBack = true ;
123146 cb ( err ) ;
124147 return ;
@@ -130,9 +153,9 @@ Pool.prototype.end = function(cb) {
130153 return ;
131154 }
132155
133- for ( var i = 0 ; i < this . _allConnections . length ; i ++ ) {
134- connection = this . _allConnections . get ( i ) ;
135- connection . _realEnd ( endCB ) ;
156+ var connection ;
157+ while ( ( connection = this . _allConnections . shift ( ) ) ) {
158+ this . _closeConnection ( connection , endCB ) ;
136159 }
137160} ;
138161
@@ -184,14 +207,56 @@ Pool.prototype.execute = function(sql, values, cb) {
184207 } ) ;
185208} ;
186209
210+ Pool . prototype . _manageExpiredTimer = function ( ) {
211+ var hasExtra = this . _allConnections . length > this . config . minConnections ;
212+ if ( hasExtra && ! this . _expiredTimer ) {
213+ this . _expiredTimer = Timers . setInterval (
214+ Pool . prototype . _closeIdleConnections . bind ( this ) ,
215+ Math . min ( 15 , this . config . idleTimeout ) * 1000
216+ ) ;
217+ } else if ( ! hasExtra && this . _expiredTimer ) {
218+ Timers . clearInterval ( this . _expiredTimer ) ;
219+ this . _expiredTimer = null ;
220+ }
221+ } ;
222+
223+ Pool . prototype . _closeIdleConnections = function ( ) {
224+ var now = Date . now ( ) ;
225+ var timeout = this . config . idleTimeout * 1000 ;
226+ var length = this . _freeConnections . length ;
227+ var numExtra = this . _allConnections . length - this . config . minConnections ;
228+ for ( var i = 0 ; numExtra > 0 && i < length ; i ++ ) {
229+ var conn = this . _freeConnections . get ( i ) ;
230+
231+ if ( now > conn . _lastReleased + timeout ) {
232+ // This connection has been unused for longer than the timeout
233+ this . _closeConnection ( conn ) ;
234+ // decrement i and length as the length will be reduced by 1 by closeConnection
235+ i -- ;
236+ length -- ;
237+ numExtra -- ;
238+ }
239+ }
240+ this . _manageExpiredTimer ( ) ;
241+ } ;
242+
187243Pool . prototype . _removeConnection = function ( connection ) {
188244 // Remove connection from all connections
189245 spliceConnection ( this . _allConnections , connection ) ;
190246
191247 // Remove connection from free connections
192248 spliceConnection ( this . _freeConnections , connection ) ;
193249
194- this . releaseConnection ( connection ) ;
250+ if ( ! connection . _closing && ! connection . _closed ) {
251+ this . releaseConnection ( connection ) ;
252+ }
253+
254+ this . _manageExpiredTimer ( ) ;
255+ } ;
256+
257+ Pool . prototype . _closeConnection = function ( connection , cb ) {
258+ connection . _realEnd ( cb ) ;
259+ this . _removeConnection ( connection ) ;
195260} ;
196261
197262Pool . prototype . format = function ( sql , values ) {
0 commit comments