@@ -12,10 +12,11 @@ function Pool(options) {
12
12
this . config = options . config ;
13
13
this . config . connectionConfig . pool = this ;
14
14
15
- this . _allConnections = [ ] ;
16
- this . _freeConnections = [ ] ;
17
- this . _connectionQueue = [ ] ;
18
- this . _closed = false ;
15
+ this . _acquiringConnections = [ ] ;
16
+ this . _allConnections = [ ] ;
17
+ this . _freeConnections = [ ] ;
18
+ this . _connectionQueue = [ ] ;
19
+ this . _closed = false ;
19
20
}
20
21
21
22
Pool . prototype . getConnection = function ( cb ) {
@@ -38,24 +39,22 @@ Pool.prototype.getConnection = function (cb) {
38
39
if ( this . config . connectionLimit === 0 || this . _allConnections . length < this . config . connectionLimit ) {
39
40
connection = new PoolConnection ( this , { config : this . config . newConnectionConfig ( ) } ) ;
40
41
42
+ this . _acquiringConnections . push ( connection ) ;
41
43
this . _allConnections . push ( connection ) ;
42
44
43
- connection . _pool = null ;
44
- return connection . connect ( { timeout : this . config . acquireTimeout } , function ( err ) {
45
+ return connection . connect ( { timeout : this . config . acquireTimeout } , function onConnect ( err ) {
46
+ spliceConnection ( pool . _acquiringConnections , connection ) ;
47
+
45
48
if ( pool . _closed ) {
46
- connection . destroy ( ) ;
47
- pool . _removeConnection ( connection ) ;
48
- cb ( new Error ( 'Pool is closed.' ) ) ;
49
- return ;
49
+ err = new Error ( 'Pool is closed.' ) ;
50
50
}
51
51
52
52
if ( err ) {
53
- pool . _removeConnection ( connection ) ;
53
+ pool . _purgeConnection ( connection ) ;
54
54
cb ( err ) ;
55
55
return ;
56
56
}
57
57
58
- connection . _pool = pool ;
59
58
pool . emit ( 'connection' , connection ) ;
60
59
cb ( null , connection ) ;
61
60
} ) ;
@@ -77,30 +76,33 @@ Pool.prototype.acquireConnection = function acquireConnection(connection, cb) {
77
76
78
77
var pool = this ;
79
78
80
- connection . _pool = null ;
81
- connection . ping ( { timeout : this . config . acquireTimeout } , function ( err ) {
82
- if ( ! err && ! pool . _closed ) {
83
- connection . _pool = pool ;
84
- cb ( null , connection ) ;
85
- return ;
86
- }
79
+ this . _acquiringConnections . push ( connection ) ;
87
80
88
- connection . destroy ( ) ;
81
+ connection . ping ( { timeout : this . config . acquireTimeout } , function onPing ( err ) {
82
+ spliceConnection ( pool . _acquiringConnections , connection ) ;
89
83
90
84
if ( pool . _closed ) {
91
- pool . _removeConnection ( connection ) ;
92
- cb ( new Error ( 'Pool is closed.' ) ) ;
85
+ err = new Error ( 'Pool is closed.' ) ;
86
+ }
87
+
88
+ if ( err ) {
89
+ pool . _connectionQueue . unshift ( cb ) ;
90
+ pool . _purgeConnection ( connection ) ;
93
91
return ;
94
92
}
95
93
96
- pool . _connectionQueue . unshift ( cb ) ;
97
- pool . _removeConnection ( connection ) ;
94
+ cb ( null , connection ) ;
98
95
} ) ;
99
96
} ;
100
97
101
98
Pool . prototype . releaseConnection = function releaseConnection ( connection ) {
102
99
var cb ;
103
100
101
+ if ( this . _acquiringConnections . indexOf ( connection ) !== - 1 ) {
102
+ // connection is being acquired
103
+ return ;
104
+ }
105
+
104
106
if ( connection . _pool ) {
105
107
if ( connection . _pool !== this ) {
106
108
throw new Error ( 'Connection released to wrong pool' ) ;
@@ -143,39 +145,26 @@ Pool.prototype.end = function (cb) {
143
145
} ;
144
146
}
145
147
146
- var calledBack = false ;
147
- var closedConnections = 0 ;
148
- var connection ;
148
+ var calledBack = false ;
149
+ var waitingClose = this . _allConnections . length ;
149
150
150
- var endCB = function ( err ) {
151
+ function onEnd ( err ) {
151
152
if ( calledBack ) {
152
153
return ;
153
154
}
154
155
155
- if ( err || this . _allConnections . length === 0 ) {
156
+ if ( err || -- waitingClose === 0 ) {
156
157
calledBack = true ;
157
158
return cb ( err ) ;
158
159
}
159
- } . bind ( this ) ;
160
-
161
- if ( this . _allConnections . length === 0 ) {
162
- return process . nextTick ( endCB ) ;
163
160
}
164
161
165
- while ( this . _allConnections . length ) {
166
- connection = this . _allConnections [ 0 ] ;
167
-
168
- if ( connection . _pool === this ) {
169
- closedConnections ++ ;
170
- connection . _pool = null ;
171
- connection . _realEnd ( endCB ) ;
172
- }
173
-
174
- this . _removeConnection ( connection ) ;
162
+ if ( waitingClose === 0 ) {
163
+ return process . nextTick ( cb ) ;
175
164
}
176
165
177
- if ( closedConnections = == 0 ) {
178
- return process . nextTick ( endCB ) ;
166
+ while ( this . _allConnections . length ! == 0 ) {
167
+ this . _purgeConnection ( this . _allConnections [ 0 ] , onEnd ) ;
179
168
}
180
169
} ;
181
170
@@ -229,32 +218,31 @@ Pool.prototype._enqueueCallback = function _enqueueCallback(callback) {
229
218
this . emit ( 'enqueue' ) ;
230
219
} ;
231
220
232
- Pool . prototype . _purgeConnection = function _purgeConnection ( connection ) {
233
- var pool = this ;
221
+ Pool . prototype . _purgeConnection = function _purgeConnection ( connection , callback ) {
222
+ var cb = callback || function ( ) { } ;
234
223
235
- connection . _realEnd ( function ( err ) {
236
- if ( err ) {
237
- connection . destroy ( ) ;
238
- }
224
+ if ( connection . state === 'disconnected' ) {
225
+ connection . destroy ( ) ;
226
+ }
239
227
240
- pool . _removeConnection ( connection ) ;
241
- } ) ;
228
+ this . _removeConnection ( connection ) ;
229
+
230
+ if ( connection . state !== 'disconnected' && ! connection . _protocol . _quitSequence ) {
231
+ connection . _realEnd ( cb ) ;
232
+ return ;
233
+ }
234
+
235
+ process . nextTick ( cb ) ;
242
236
} ;
243
237
244
238
Pool . prototype . _removeConnection = function ( connection ) {
245
- var index ;
246
-
247
239
connection . _pool = null ;
248
240
249
- if ( ( index = this . _allConnections . indexOf ( connection ) ) !== - 1 ) {
250
- // Remove connection from all connections
251
- this . _allConnections . splice ( index , 1 ) ;
252
- }
241
+ // Remove connection from all connections
242
+ spliceConnection ( this . _allConnections , connection ) ;
253
243
254
- if ( ( index = this . _freeConnections . indexOf ( connection ) ) !== - 1 ) {
255
- // Remove connection from free connections
256
- this . _freeConnections . splice ( index , 1 ) ;
257
- }
244
+ // Remove connection from free connections
245
+ spliceConnection ( this . _freeConnections , connection ) ;
258
246
259
247
this . releaseConnection ( connection ) ;
260
248
} ;
@@ -266,3 +254,11 @@ Pool.prototype.escape = function(value) {
266
254
Pool . prototype . escapeId = function escapeId ( value ) {
267
255
return mysql . escapeId ( value , false ) ;
268
256
} ;
257
+
258
+ function spliceConnection ( array , connection ) {
259
+ var index ;
260
+ if ( ( index = array . indexOf ( connection ) ) !== - 1 ) {
261
+ // Remove connection from all connections
262
+ array . splice ( index , 1 ) ;
263
+ }
264
+ }
0 commit comments