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,14 @@ function Pool(options) {
1819 this . _freeConnections = new Queue ( ) ;
1920 this . _connectionQueue = new Queue ( ) ;
2021 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+ }
2130}
2231
2332Pool . prototype . getConnection = function ( cb ) {
@@ -82,6 +91,7 @@ Pool.prototype.getConnection = function(cb) {
8291Pool . prototype . releaseConnection = function ( connection ) {
8392 var cb ;
8493
94+ connection . _lastReleased = Date . now ( ) ;
8595 if ( ! connection . _pool ) {
8696 // The connection has been removed from the pool and is no longer good.
8797 if ( this . _connectionQueue . length ) {
@@ -95,6 +105,7 @@ Pool.prototype.releaseConnection = function(connection) {
95105 process . nextTick ( cb . bind ( null , null , connection ) ) ;
96106 } else {
97107 this . _freeConnections . push ( connection ) ;
108+ this . _manageExpiredTimer ( ) ;
98109 }
99110} ;
100111
@@ -111,14 +122,14 @@ Pool.prototype.end = function(cb) {
111122
112123 var calledBack = false ;
113124 var closedConnections = 0 ;
114- var connection ;
125+ var numConnections = this . _allConnections . length ;
115126
116127 var endCB = function ( err ) {
117128 if ( calledBack ) {
118129 return ;
119130 }
120131
121- if ( err || ++ closedConnections >= this . _allConnections . length ) {
132+ if ( err || ++ closedConnections >= numConnections ) {
122133 calledBack = true ;
123134 cb ( err ) ;
124135 return ;
@@ -130,9 +141,9 @@ Pool.prototype.end = function(cb) {
130141 return ;
131142 }
132143
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 ) ;
136147 }
137148} ;
138149
@@ -184,14 +195,58 @@ Pool.prototype.execute = function(sql, values, cb) {
184195 } ) ;
185196} ;
186197
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 ; i < length ; i ++ ) {
217+ if ( numExtra <= 0 ) {
218+ break ;
219+ }
220+ var conn = this . _freeConnections . get ( i ) ;
221+
222+ if ( now > conn . _lastReleased + timeout ) {
223+ // This connection has been unused for longer than the timeout
224+ this . _closeConnection ( conn ) ;
225+ // decrement i and length as the length will be reduced by 1 by closeConnection
226+ i -- ;
227+ length -- ;
228+ }
229+ }
230+ this . _manageExpiredTimer ( ) ;
231+ } ;
232+
187233Pool . prototype . _removeConnection = function ( connection ) {
188234 // Remove connection from all connections
189235 spliceConnection ( this . _allConnections , connection ) ;
190236
191237 // Remove connection from free connections
192238 spliceConnection ( this . _freeConnections , connection ) ;
193239
194- this . releaseConnection ( connection ) ;
240+ if ( ! connection . _closing && ! connection . _closed ) {
241+ this . releaseConnection ( connection ) ;
242+ }
243+
244+ this . _manageExpiredTimer ( ) ;
245+ } ;
246+
247+ Pool . prototype . _closeConnection = function ( connection , cb ) {
248+ connection . _realEnd ( cb ) ;
249+ this . _removeConnection ( connection ) ;
195250} ;
196251
197252Pool . prototype . format = function ( sql , values ) {
0 commit comments