Browse files

[api] Add reconnection to godot client

  • Loading branch information...
1 parent 0495457 commit fb2f77440e5ab5087ec0e48e4b0903e4debf55f5 @mmalecki mmalecki committed Mar 24, 2013
Showing with 60 additions and 16 deletions.
  1. +58 −15 lib/godot/net/client.js
  2. +2 −1 package.json
View
73 lib/godot/net/client.js
@@ -6,7 +6,10 @@
*/
var dgram = require('dgram'),
- net = require('net');
+ net = require('net'),
+ util = require('util'),
+ backoff = require('backoff'),
+ EventEmitter = require('events').EventEmitter;
//
// ### function Server (options)
@@ -19,6 +22,8 @@ var dgram = require('dgram'),
// Producers attached to a TCP or UDP client.
//
var Client = module.exports = function Client(options) {
+ EventEmitter.call(this);
+
if (!options || !options.type
|| !~['tcp', 'udp', 'unix'].indexOf(options.type)) {
throw new Error('Cannot create client without type: udp, tcp, unix');
@@ -30,6 +35,7 @@ var Client = module.exports = function Client(options) {
this.host = options.host;
this.port = options.port;
this.path = options.path;
+ this.reconnect = options.reconnect;
this.producers = {};
this.handlers = {
data: {},
@@ -42,6 +48,7 @@ var Client = module.exports = function Client(options) {
});
}
};
+util.inherits(Client, EventEmitter);
//
// ### function add (producer)
@@ -117,7 +124,28 @@ Client.prototype.write = function (data) {
// Opens the underlying network connection for this client.
//
Client.prototype.connect = function (port, host, callback) {
- var err;
+ var self = this,
+ connectBackoff, backoffType;
+
+ if (this.reconnect) {
+ if (typeof this.reconnect === 'object') {
+ backoffType = this.reconnect.type || 'expotential';
+ connectBackoff = backoff[backoffType](this.reconnect);
+ connectBackoff.failAfter(this.reconnect.maxTries || 10);
+ }
+ else {
+ connectBackoff = backoff.expotential();
+ connectBackoff.failAfter(10);
+ }
+
+ connectBackoff.on('fail', function (err) {
+ self.emit('error', err);
+ });
+
+ connectBackoff.on('ready', function () {
+ connect();
+ });
+ }
//
// Do some fancy arguments parsing to support everything
@@ -137,14 +165,40 @@ Client.prototype.connect = function (port, host, callback) {
});
function error (arg) {
- err = new Error(arg + ' required to connect');
+ var err = new Error(arg + ' required to connect');
if (callback) {
return callback(err);
}
throw err;
}
+ function onError(err) {
+ return connectBackoff ? connectBackoff.backoff(err) : self.emit('error', err);
+ }
+
+ function connect() {
+ if (self.type === 'tcp') {
+ self.socket = net.connect({ port: self.port, host: self.host }, callback);
+ }
+ else if (self.type === 'udp') {
+ self.socket = dgram.createSocket('udp4');
+ if (callback) {
+ process.nextTick(callback);
+ }
+ }
+ else if (self.type === 'unix') {
+ self.socket = net.connect({ path: self.path }, callback);
+ }
+
+ self.socket.on('error', onError);
+ self.socket.on('connect', function () {
+ if (connectBackoff) {
+ connectBackoff.reset();
+ }
+ });
+ }
+
// Split cases due to unix using `this.path`
if (this.type === 'tcp' || this.type === 'udp') {
this.port = port || this.port;
@@ -162,18 +216,7 @@ Client.prototype.connect = function (port, host, callback) {
}
}
- if (this.type === 'tcp') {
- this.socket = net.connect({ port: this.port, host: this.host }, callback);
- }
- else if (this.type === 'udp') {
- this.socket = dgram.createSocket('udp4');
- if (callback) {
- process.nextTick(callback);
- }
- }
- else if (this.type === 'unix') {
- this.socket = net.connect({ path: this.path }, callback);
- }
+ connect();
};
//
View
3 package.json
@@ -21,7 +21,8 @@
"sendgrid-web": "0.0.2",
"telenode": "0.0.3",
"utile": "0.1.7",
- "window-stream": "~0.3.1"
+ "window-stream": "~0.3.1",
+ "backoff": "2.0.x"
},
"devDependencies": {
"optimist": "0.3.4",

0 comments on commit fb2f774

Please sign in to comment.