Skip to content

Commit 69115a2

Browse files
committed
Remove destroyed promise pool connections from pool
- proxy promise pool connection destroy calls to pool connection destroy method, rather than non-pool connection destroy method
1 parent 5719e9f commit 69115a2

File tree

3 files changed

+133
-69
lines changed

3 files changed

+133
-69
lines changed

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ module.exports.createServer = function(handler) {
3333
return s;
3434
};
3535

36+
exports.PoolConnection = require('./lib/pool_connection');
3637
exports.escape = SqlString.escape;
3738
exports.escapeId = SqlString.escapeId;
3839
exports.format = SqlString.format;

promise.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,19 @@ PromisePreparedStatementInfo.prototype.close = function() {
299299
'format'
300300
]);
301301

302+
function PromisePoolConnection() {
303+
PromiseConnection.apply(this, arguments);
304+
}
305+
306+
util.inherits(PromisePoolConnection, PromiseConnection);
307+
308+
PromisePoolConnection.prototype.destroy = function() {
309+
return core.PoolConnection.prototype.destroy.apply(
310+
this.connection,
311+
arguments
312+
);
313+
};
314+
302315
function PromisePool(pool, Promise) {
303316
this.pool = pool;
304317
this.Promise = Promise;
@@ -316,7 +329,7 @@ PromisePool.prototype.getConnection = function() {
316329
if (err) {
317330
reject(err);
318331
} else {
319-
resolve(new PromiseConnection(coreConnection, self.Promise));
332+
resolve(new PromisePoolConnection(coreConnection, self.Promise));
320333
}
321334
});
322335
});

test/integration/promise-wrappers/test-promise-wrappers.js

Lines changed: 118 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -174,67 +174,77 @@ function testPreparedError() {
174174

175175
function testEventsConnect() {
176176
var connResolved;
177-
var connPromise = createConnection(config).then(function(conn) {
178-
connResolved = conn;
179-
var events = 0;
180-
181-
var expectedListeners = {
182-
error: 1,
183-
drain: 0,
184-
connect: 0,
185-
enqueue: 0,
186-
end: 0
187-
};
188-
for (var eventName in expectedListeners) {
189-
assert.equal(conn.connection.listenerCount(eventName), expectedListeners[eventName], eventName);
190-
}
191-
192-
conn
193-
.once('error', function() {
194-
assert.equal(this, conn);
195-
++events;
196-
})
197-
.once('drain', function() {
198-
assert.equal(this, conn);
199-
++events;
200-
})
201-
.once('connect', function() {
202-
assert.equal(this, conn);
203-
++events;
204-
})
205-
.once('enqueue', function() {
206-
assert.equal(this, conn);
207-
++events;
208-
})
209-
.once('end', function() {
210-
assert.equal(this, conn);
211-
++events;
212-
213-
doneEventsConnect = events === 5;
214-
});
215-
216-
conn.connection.emit('error', new Error());
217-
conn.connection.emit('drain');
218-
conn.connection.emit('connect');
219-
conn.connection.emit('enqueue');
220-
conn.connection.emit('end');
177+
var connPromise = createConnection(config)
178+
.then(function(conn) {
179+
connResolved = conn;
180+
var events = 0;
181+
182+
var expectedListeners = {
183+
error: 1,
184+
drain: 0,
185+
connect: 0,
186+
enqueue: 0,
187+
end: 0
188+
};
189+
for (var eventName in expectedListeners) {
190+
assert.equal(
191+
conn.connection.listenerCount(eventName),
192+
expectedListeners[eventName],
193+
eventName
194+
);
195+
}
221196

222-
expectedListeners.error = 0;
223-
for (var eventName in expectedListeners) {
224-
assert.equal(conn.connection.listenerCount(eventName), expectedListeners[eventName], eventName);
225-
}
197+
conn
198+
.once('error', function() {
199+
assert.equal(this, conn);
200+
++events;
201+
})
202+
.once('drain', function() {
203+
assert.equal(this, conn);
204+
++events;
205+
})
206+
.once('connect', function() {
207+
assert.equal(this, conn);
208+
++events;
209+
})
210+
.once('enqueue', function() {
211+
assert.equal(this, conn);
212+
++events;
213+
})
214+
.once('end', function() {
215+
assert.equal(this, conn);
216+
++events;
217+
218+
doneEventsConnect = events === 5;
219+
});
220+
221+
conn.connection.emit('error', new Error());
222+
conn.connection.emit('drain');
223+
conn.connection.emit('connect');
224+
conn.connection.emit('enqueue');
225+
conn.connection.emit('end');
226+
227+
expectedListeners.error = 0;
228+
for (var eventName in expectedListeners) {
229+
assert.equal(
230+
conn.connection.listenerCount(eventName),
231+
expectedListeners[eventName],
232+
eventName
233+
);
234+
}
226235

227-
conn.end();
228-
}).catch(function(err) {
229-
console.log(err);
230-
if (connResolved) {
231-
connResolved.end();
232-
} else {
233-
console.log(
234-
'Warning: promise rejected before executing prepared statement'
235-
);
236-
}
237-
});
236+
conn.end();
237+
})
238+
.catch(function(err) {
239+
console.log(err);
240+
if (connResolved) {
241+
connResolved.end();
242+
} else {
243+
console.log(
244+
'Warning: promise rejected before executing prepared statement'
245+
);
246+
}
247+
});
238248
}
239249

240250
function testBasicPool() {
@@ -309,7 +319,11 @@ function testEventsPool() {
309319
release: 0
310320
};
311321
for (var eventName in expectedListeners) {
312-
assert.equal(pool.pool.listenerCount(eventName), expectedListeners[eventName], eventName);
322+
assert.equal(
323+
pool.pool.listenerCount(eventName),
324+
expectedListeners[eventName],
325+
eventName
326+
);
313327
}
314328

315329
pool
@@ -338,7 +352,11 @@ function testEventsPool() {
338352
pool.pool.emit('release');
339353

340354
for (var eventName in expectedListeners) {
341-
assert.equal(pool.pool.listenerCount(eventName), expectedListeners[eventName], eventName);
355+
assert.equal(
356+
pool.pool.listenerCount(eventName),
357+
expectedListeners[eventName],
358+
eventName
359+
);
342360
}
343361
}
344362

@@ -410,6 +428,37 @@ function testChangeUser() {
410428
});
411429
}
412430

431+
function timebomb(fuse) {
432+
var timebomb;
433+
434+
return {
435+
arm() {
436+
timebomb = setTimeout(() => {
437+
throw new Error(`Timebomb not defused within ${fuse}ms`);
438+
}, fuse);
439+
},
440+
defuse() {
441+
clearTimeout(timebomb);
442+
}
443+
};
444+
}
445+
446+
function testPoolConnectionDestroy() {
447+
// Only allow one connection
448+
const options = Object.assign({ connectionLimit: 1 }, config);
449+
const pool = createPool(options);
450+
451+
const bomb = timebomb(2000);
452+
453+
pool
454+
.getConnection()
455+
.then(connection => connection.destroy())
456+
.then(bomb.arm)
457+
.then(() => pool.getConnection())
458+
.then(bomb.defuse)
459+
.then(() => pool.end());
460+
}
461+
413462
testBasic();
414463
testErrors();
415464
testObjParams();
@@ -420,18 +469,19 @@ testErrorsPool();
420469
testObjParamsPool();
421470
testEventsPool();
422471
testChangeUser();
472+
testPoolConnectionDestroy();
423473

424474
process.on('exit', function() {
425475
if (skipTest) {
426476
return;
427477
}
428-
assert.equal(doneCalled, true);
429-
assert.equal(exceptionCaught, true);
430-
assert.equal(doneEventsConnect, true);
431-
assert.equal(doneCalledPool, true);
432-
assert.equal(exceptionCaughtPool, true);
433-
assert.equal(doneEventsPool, true);
434-
assert.equal(doneChangeUser, true);
478+
assert.equal(doneCalled, true, 'done not called');
479+
assert.equal(exceptionCaught, true, 'exception not caught');
480+
assert.equal(doneEventsConnect, true, 'wrong number of connection events');
481+
assert.equal(doneCalledPool, true, 'pool done not called');
482+
assert.equal(exceptionCaughtPool, true, 'pool exception not caught');
483+
assert.equal(doneEventsPool, true, 'wrong number of pool connection events');
484+
assert.equal(doneChangeUser, true, 'user not changed');
435485
});
436486

437487
process.on('unhandledRejection', function(err) {

0 commit comments

Comments
 (0)