不要怂,就是干,撸起袖子干!

Commit 66c45e01 by Mick Hansen

Merge pull request #2450 from findhit/feature/connection-manager-handle-disconnects

dialect.mysql.connection-manager: handleDisconnects
2 parents 16523b00 1c8fbbee
...@@ -7,7 +7,7 @@ var Pooling = require('generic-pool') ...@@ -7,7 +7,7 @@ var Pooling = require('generic-pool')
max: 5, max: 5,
min: 0, min: 0,
idle: 10000, idle: 10000,
handleDisconnects: false handleDisconnects: true
} }
, ConnectionManager; , ConnectionManager;
...@@ -113,6 +113,9 @@ ConnectionManager.prototype.initPools = function () { ...@@ -113,6 +113,9 @@ ConnectionManager.prototype.initPools = function () {
self.pool.write.acquire(callback, priority); self.pool.write.acquire(callback, priority);
} }
}, },
destroy: function(connection) {
return self.pool[connection.queryType].destroy(connection);
},
drain: function() { drain: function() {
self.pool.read.drain(); self.pool.read.drain();
self.pool.write.drain(); self.pool.write.drain();
......
...@@ -58,6 +58,20 @@ ConnectionManager.prototype.connect = function(config) { ...@@ -58,6 +58,20 @@ ConnectionManager.prototype.connect = function(config) {
return; return;
} }
if (config.pool.handleDisconnects) {
// Connection to the MySQL server is usually
// lost due to either server restart, or a
// connnection idle timeout (the wait_timeout
// server variable configures this)
//
// See [stackoverflow answer](http://stackoverflow.com/questions/20210522/nodejs-mysql-error-connection-lost-the-server-closed-the-connection)
connection.on('error', function (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
// Remove it from read/write pool
self.pool.destroy(connection);
}
});
}
resolve(connection); resolve(connection);
}); });
...@@ -66,6 +80,13 @@ ConnectionManager.prototype.connect = function(config) { ...@@ -66,6 +80,13 @@ ConnectionManager.prototype.connect = function(config) {
}); });
}; };
ConnectionManager.prototype.disconnect = function(connection) { ConnectionManager.prototype.disconnect = function(connection) {
// Dont disconnect connections with an ended protocol
// That wil trigger a connection error
if (connection._protocol._ended) {
return Promise.resolve();
}
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
connection.end(function(err) { connection.end(function(err) {
if (err) return reject(err); if (err) return reject(err);
...@@ -74,7 +95,7 @@ ConnectionManager.prototype.disconnect = function(connection) { ...@@ -74,7 +95,7 @@ ConnectionManager.prototype.disconnect = function(connection) {
}); });
}; };
ConnectionManager.prototype.validate = function(connection) { ConnectionManager.prototype.validate = function(connection) {
return connection && ['disconnected', 'protocol_error'].indexOf(connection.state) !== -1; return connection && ['disconnected', 'protocol_error'].indexOf(connection.state) === -1;
}; };
module.exports = ConnectionManager; module.exports = ConnectionManager;
...@@ -52,5 +52,69 @@ if (Support.dialectIsMySQL()) { ...@@ -52,5 +52,69 @@ if (Support.dialectIsMySQL()) {
}) })
}) })
}) })
// This should run only on direct mysql
if (Support.dialectIsMySQL(true)) {
it('should maintain connection', function () {
var sequelize = Support.createSequelizeInstance({pool: {min: 1, max: 1, handleDisconnects: true, idle: 5000}}),
cm = sequelize.connectionManager,
conn;
return sequelize.sync()
.then(function () {
return cm.getConnection();
})
.then(function (connection) {
// Save current connection
conn = connection;
})
.then(function () {
return cm.releaseConnection(conn);
})
.then(function () {
// Get next available connection
return cm.getConnection();
})
.then(function (connection) {
// Old threadId should be different from current new one
expect(conn.threadId).to.be.equal(connection.threadId);
expect(cm.validate(conn)).to.be.ok;
return cm.releaseConnection(connection);
});
});
it('should work with handleDisconnects', function () {
var sequelize = Support.createSequelizeInstance({pool: {min: 1, max: 1, handleDisconnects: true, idle: 5000}}),
cm = sequelize.connectionManager,
conn;
return sequelize.sync()
.then(function (){
return cm.getConnection();
}) })
.then(function (connection) {
// Save current connection
conn = connection;
// simulate a unexpected end
connection._protocol.end();
})
.then(function () {
return cm.releaseConnection(conn);
})
.then(function () {
// Get next available connection
return cm.getConnection();
})
.then(function (connection) {
// Old threadId should be different from current new one
expect(conn.threadId).to.not.be.equal(connection.threadId);
expect(cm.validate(conn)).to.not.be.ok;
return cm.releaseConnection(connection);
});
});
}
});
} }
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!