Skip to content

Commit

Permalink
Fixed reconnect logic in MySQL adapter, added test
Browse files Browse the repository at this point in the history
  • Loading branch information
mde committed Mar 3, 2014
1 parent 98e3e17 commit acb8b43
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
22 changes: 15 additions & 7 deletions lib/adapters/sql/mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ var utils = require('utilities')
, model = require('../../../lib')
, Query = require('../../../lib/query/query').Query
, BaseAdapter = require('./base').Adapter
, RECONNECT_TRIES_LIMIT = 3
, reconnectAttempts = 0
, Adapter
, _baseConfig;

Expand Down Expand Up @@ -39,21 +41,27 @@ utils.mixin(Adapter.prototype, new (function () {

this.COLUMN_NAME_DELIMITER = '`';

this.handleDisconnect = function () {
// Pseudo-private -- utility and for testing only
this._getClient = function () {
return mysql.createConnection(this.config);
};

this._handleDisconnect = function (callback) {
var self = this;
setTimeout(function() {
self.client = mysql.createConnection(self.config);
self.connect();
self.client = self._getClient();
self.connect(callback);
}, Math.pow(3, reconnectAttempts) * 1000);
reconnectAttempts++;
};

this.init = function () {
var self = this;
this.client = mysql.createConnection(this.config);
this.client = this._getClient();
this.client.on('error', function(err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST' && reconnectAttempts < RECONNECT_TRIES_LIMIT) {
self.handleDisconnect();
if (err.code === 'PROTOCOL_CONNECTION_LOST' &&
reconnectAttempts < RECONNECT_TRIES_LIMIT) {
self._handleDisconnect();
};
});
};
Expand All @@ -64,7 +72,7 @@ utils.mixin(Adapter.prototype, new (function () {
this.client.connect(function (err, data) {
if (err) {
if (reconnectAttempts < RECONNECT_TRIES_LIMIT) {
self.handleDisconnect();
self._handleDisconnect(callback);
} else {
self.emit('error', err);
cb(err);
Expand Down
29 changes: 29 additions & 0 deletions test/integration/adapters/sql/mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,35 @@ tests = {
assert.ok(adapter instanceof Adapter);
}

, 'test reconnect logic': function (next) {
// Get a reference to the original client func
var origGetClient = adapter._getClient;
// Punch out the client func with one that returns a client
// whose `connect` method always produces an error
adapter._getClient = function () {
var client = origGetClient.call(adapter);
// Always error
client.connect = function (cb) {
cb({}, null);
};
return client;
};
// Disconnect, and try to reconnect -- this will fail
adapter.disconnect(function (err, data) {
// Until the _getClient function is replaced, this will continue
// retrying, once we put it back, reconnect will succeed and
// tests will resume
adapter.connect(function (err, data) {
next();
});
// Wait three seconds, restore the _getClient func to return
// a good client
setTimeout(function () {
adapter._getClient = origGetClient;
}, 3000);
});
}

, 'test exec': function (next) {
adapter.exec('CREATE TABLE foo (bar varchar(256) ); DROP TABLE foo;',
function (err, data) {
Expand Down

0 comments on commit acb8b43

Please sign in to comment.