Skip to content

Commit f0dfda8

Browse files
seangarnerdougwilson
authored andcommitted
Re-use connection from pool after conn.changeUser is used
closes #837 closes #1088
1 parent 2a42a12 commit f0dfda8

File tree

4 files changed

+56
-29
lines changed

4 files changed

+56
-29
lines changed

Changes.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ you spot any mistakes.
88

99
* Fix a sync callback when sequence enqueue fails #1147
1010
* Provide static require analysis
11+
* Re-use connection from pool after `conn.changeUser` is used #837 #1088
1112

1213
## v2.7.0 (2015-05-27)
1314

lib/Pool.js

+30-8
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,12 @@ Pool.prototype.acquireConnection = function acquireConnection(connection, cb) {
7474
throw new Error('Connection acquired from wrong pool.');
7575
}
7676

77-
var pool = this;
77+
var changeUser = this._needsChangeUser(connection);
78+
var pool = this;
7879

7980
this._acquiringConnections.push(connection);
8081

81-
connection.ping({timeout: this.config.acquireTimeout}, function onPing(err) {
82+
function onOperationComplete(err) {
8283
spliceConnection(pool._acquiringConnections, connection);
8384

8485
if (pool._closed) {
@@ -91,12 +92,26 @@ Pool.prototype.acquireConnection = function acquireConnection(connection, cb) {
9192
return;
9293
}
9394

95+
if (changeUser) {
96+
pool.emit('connection', connection);
97+
}
98+
9499
cb(null, connection);
95-
});
100+
}
101+
102+
if (changeUser) {
103+
// restore user back to pool configuration
104+
connection.config = this.config.newConnectionConfig();
105+
connection.changeUser({timeout: this.config.acquireTimeout}, onOperationComplete);
106+
} else {
107+
// ping connection
108+
connection.ping({timeout: this.config.acquireTimeout}, onOperationComplete);
109+
}
96110
};
97111

98112
Pool.prototype.releaseConnection = function releaseConnection(connection) {
99113
var cb;
114+
var pool = this;
100115

101116
if (this._acquiringConnections.indexOf(connection) !== -1) {
102117
// connection is being acquired
@@ -108,11 +123,7 @@ Pool.prototype.releaseConnection = function releaseConnection(connection) {
108123
throw new Error('Connection released to wrong pool');
109124
}
110125

111-
if (connection._purge) {
112-
// purge connection from pool
113-
this._purgeConnection(connection);
114-
return;
115-
} else if (this._freeConnections.indexOf(connection) !== -1) {
126+
if (this._freeConnections.indexOf(connection) !== -1) {
116127
// connection already in free connection pool
117128
// this won't catch all double-release cases
118129
throw new Error('Connection already released');
@@ -218,6 +229,17 @@ Pool.prototype._enqueueCallback = function _enqueueCallback(callback) {
218229
this.emit('enqueue');
219230
};
220231

232+
Pool.prototype._needsChangeUser = function _needsChangeUser(connection) {
233+
var connConfig = connection.config;
234+
var poolConfig = this.config.connectionConfig;
235+
236+
// check if changeUser values are different
237+
return connConfig.user !== poolConfig.user
238+
|| connConfig.database !== poolConfig.database
239+
|| connConfig.password !== poolConfig.password
240+
|| connConfig.charsetNumber !== poolConfig.charsetNumber;
241+
}
242+
221243
Pool.prototype._purgeConnection = function _purgeConnection(connection, callback) {
222244
var cb = callback || function () {};
223245

lib/PoolConnection.js

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
var inherits = require('util').inherits;
22
var Connection = require('./Connection')
3-
var __changeUser = Connection.prototype.changeUser;
43

54
module.exports = PoolConnection;
65
inherits(PoolConnection, Connection);
76

87
function PoolConnection(pool, options) {
98
Connection.call(this, options);
109
this._pool = pool;
11-
this._purge = false
1210

1311
// When a fatal error occurs the connection's protocol ends, which will cause
1412
// the connection to end as well, thus we only need to watch for the end event
@@ -21,14 +19,9 @@ function PoolConnection(pool, options) {
2119
});
2220
}
2321

24-
PoolConnection.prototype.changeUser = function changeUser(options, callback) {
25-
this._purge = true;
26-
27-
return __changeUser.apply(this, arguments);
28-
};
29-
3022
PoolConnection.prototype.release = function release() {
3123
var pool = this._pool;
24+
var connection = this;
3225

3326
if (!pool || pool._closed) {
3427
return;

test/unit/pool/test-change-user-eject.js renamed to test/unit/pool/test-change-user-restore.js

+24-13
Original file line numberDiff line numberDiff line change
@@ -19,38 +19,49 @@ server.listen(common.fakeServerPort, function(err) {
1919
assert.ifError(err);
2020
assert.ok(conn.threadId === 1 || conn.threadId === 2);
2121
conn0 = conn;
22-
threadId = conn.threadId;
2322
});
2423

2524
pool.getConnection(function(err, conn) {
2625
assert.ifError(err);
2726
assert.ok(conn.threadId === 1 || conn.threadId === 2);
28-
29-
var threadId = conn.threadId;
27+
threadId = conn.threadId;
3028

3129
conn.changeUser({user: 'user_2'}, function(err) {
3230
assert.ifError(err);
3331
assert.strictEqual(conn.threadId, threadId);
34-
conn.release();
35-
conn0.release();
32+
33+
conn.query('SELECT CURRENT_USER()', function (err, rows) {
34+
assert.ifError(err);
35+
assert.strictEqual(rows.length, 1);
36+
assert.strictEqual(rows[0]['CURRENT_USER()'], 'user_2@localhost');
37+
conn.release();
38+
});
3639
});
3740
});
3841

3942
pool.getConnection(function(err, conn1) {
4043
assert.ifError(err);
41-
assert.strictEqual(conn1.threadId, 3);
44+
assert.strictEqual(conn1.threadId, threadId);
4245

43-
pool.getConnection(function(err, conn2) {
46+
conn1.query('SELECT CURRENT_USER()', function (err, rows) {
4447
assert.ifError(err);
45-
assert.strictEqual(conn2.threadId, threadId);
46-
conn1.release();
47-
conn2.release();
48+
assert.strictEqual(rows.length, 1);
49+
assert.strictEqual(rows[0]['CURRENT_USER()'], 'user_1@localhost');
4850

49-
pool.end(function(err) {
51+
pool.getConnection(function(err, conn2) {
5052
assert.ifError(err);
51-
assert.strictEqual(closed, 3);
52-
server.destroy();
53+
assert.ok(conn2.threadId === 1 || conn2.threadId === 2);
54+
conn1.release();
55+
conn2.release();
56+
57+
pool.end(function(err) {
58+
assert.ifError(err);
59+
assert.strictEqual(closed, 2);
60+
server.destroy();
61+
});
5362
});
63+
64+
conn0.release();
5465
});
5566
});
5667
});

0 commit comments

Comments
 (0)