Skip to content

Commit

Permalink
fix(Endpoint): fixed a critical issue that disallowed reconnect to th…
Browse files Browse the repository at this point in the history
…e endpoint
  • Loading branch information
FGRibreau committed Nov 22, 2015
1 parent e17978b commit 094d94b
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 11 deletions.
43 changes: 33 additions & 10 deletions lib/Endpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,11 @@ module.exports = function (log, jsonPackage, tls, process) {

this.handshakenBackoff.on('backoff', this.reconnect);

this.reconnectBackoff = backoff.fibonacci({
initialDelay: opts.initialTimeout || 500,
maxDelay: opts.maxTimeout || 10000
this.reconnectBackoff = backOff(this.reconnect, {
min: 500,
max: 4000,
inc: 250
});

this.reconnectBackoff.on('backoff', this.reconnect);
}

_.extend(Endpoint.prototype, EventEmitter.prototype, {
Expand Down Expand Up @@ -185,15 +184,12 @@ module.exports = function (log, jsonPackage, tls, process) {
* @param {Error} err
*/
onClose: function (sourceWasAnError) {
log.error("[Endpoint] Connection closed " + (sourceWasAnError ? 'because of an error' : ''));
log.error("[Endpoint] Connection closed " + (sourceWasAnError ? 'because of an error:' + sourceWasAnError : ''));

this.connected = false;
this.handshaken = false;
this.handshakenBackoff.reset();
try {
this.reconnectBackoff.backoff();
} catch (no_error) {}

this.reconnectBackoff.backoff();
this.emit('close', sourceWasAnError);
},

Expand All @@ -210,3 +206,30 @@ module.exports = function (log, jsonPackage, tls, process) {

return Endpoint;
};


/**
* @param {function} onBackoff
* @param {Object} options {min, max, inc}
* @return {object}
*/
function backOff(onBackoff, options) {
var _timeout, _next;

function reset(){
clearTimeout(_timeout);
_next = options.min;
}

function backoff(){
clearTimeout(_timeout); // if backoff was called multiple times
_timeout = setTimeout(onBackoff, Math.min(_next += options.inc, options.max));
}

reset();

return {
backoff: backoff,
reset: reset
};
}
46 changes: 46 additions & 0 deletions lib/Endpoint.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,52 @@ describe('Endpoint', function () {
E.connect(port, hostname);
});

it('should reconnect after a connect', function (done) {
tls.connect = tconnect();

var E = new Endpoint(stubLocalClient(), 'myKey'),
hostname = 'ssl.redsmin.dev',
port = 433;

// 1 - the first connect to ssl.redsmin.com will pass as well as the handshake
tls.connect = tconnect(null, null, null, function (data) {
E.socket.emit('data', JSON.stringify({}));

function simulateCloseEvent() {
var step = 0;
// 2 - now override the connection to ssl.redsmin.com in order to simulate an connect error
tls.connect = function () {
simulateECONNREFUSED();

if(++step === 2){
tls.connect = tconnect(null, null, null, function (data) {
E.socket.emit('data', JSON.stringify({}));
// 3 - connect should be called again
done();
});
}


return new Socket(_.noop);
};

E.socket.emit('close');
}

function simulateECONNREFUSED() {
setTimeout(function(){
var err = new Error('ECONNREFUSED');
err.message = 'ECONNREFUSED';
E.socket.emit('error', err);
}, 50);
}

setTimeout(simulateCloseEvent, 50);
});

E.connect(port, hostname);
});

it('should onError', function (done) {
var hostname = 'ssl.redsmin.dev',
port = 433;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"scripts": {
"start": "node ./bin/redsmin",
"test": "mocha lib/**.test.js"
"test": "multi='spec=- xunit=test/file.xml doc=test/docs.html' mocha -t 5000 -R mocha-multi lib/**.test.js",
},
"bin": {
"redsmin": "./bin/redsmin"
Expand Down

0 comments on commit 094d94b

Please sign in to comment.