Comparing version 0.9.5 to 0.9.6
{ | ||
"name": "frodoio", | ||
"version": "0.9.5", | ||
"version": "0.9.6", | ||
"description": "Node.js library for distributing requests in a ring of servers", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -35,5 +35,15 @@ var Etcd = require('./promise.etcd'); | ||
function addToMaps(node) { | ||
this.hosts.push(node.value); | ||
if (!this.hostsToKeys[node.value]) { | ||
this.hostsToKeys[node.value] = []; | ||
} | ||
this.hostsToKeys[node.value].push(node.key); | ||
} | ||
Frodo.prototype.init = function () { | ||
var self = this; | ||
self.pid = process.pid; | ||
self.hosts = []; | ||
self.hostsToKeys = {}; | ||
self.hashRing = new HashRing(self.hosts, 'md5'); | ||
@@ -43,10 +53,17 @@ self.hostsWatcher = self.etcd.watcher(self.context + '/hosts', null, { recursive: true }); | ||
if (result.action == 'set' && result.node.value) { | ||
self.hosts.push(result.node.value); | ||
self.hashRing.add(result.node.value) | ||
addToMaps.call(self, result.node); | ||
self.hashRing.add(result.node.value); | ||
} else if (result.action == 'delete' && result.prevNode.value) { | ||
var indexOf = self.hosts.indexOf(result.prevNode.value); | ||
if (indexOf >= 0) { | ||
self.hosts.splice(indexOf, 1); | ||
var hostsIndexOf = self.hosts.indexOf(result.prevNode.value); | ||
var hostsToKeysIndexOf = self.hostsToKeys[result.prevNode.value].indexOf(result.prevNode.key); | ||
if (hostsIndexOf >= 0) { | ||
self.hosts.splice(hostsIndexOf, 1); | ||
self.hashRing.remove(result.prevNode.value); | ||
} | ||
if (hostsToKeysIndexOf >= 0) { | ||
self.hostsToKeys[result.prevNode.value].splice(hostsToKeysIndexOf, 1); | ||
} | ||
} | ||
@@ -56,3 +73,6 @@ }); | ||
return self.etcd.get(self.context + '/hosts', { recursive: true }).then(function (result) { | ||
if (result && result[0]) { | ||
if (result && result[0] && result[0].node.nodes) { | ||
result[0].node.nodes.forEach(function (node) { | ||
addToMaps.call(self, node); | ||
}); | ||
self.hosts = _.pluck(result[0].node.nodes, 'value'); | ||
@@ -70,13 +90,21 @@ self.hashRing.add(self.hosts); | ||
Frodo.prototype.addServer = function (server) { | ||
Frodo.prototype.addServer = function (server, options) { | ||
var self = this; | ||
var options = options || {}; | ||
return this.ready.then(function () { | ||
return self.etcd.set(self.context + '/hosts/' + server, server); | ||
return self.etcd.set(self.context + '/hosts/' + server + ':' + (options.id ? options.id : self.pid), server); | ||
}); | ||
}; | ||
Frodo.prototype.removeServer = function (server) { | ||
Frodo.prototype.removeServer = function (server, options) { | ||
var self = this; | ||
var options = options || {}; | ||
return this.ready.then(function () { | ||
return self.etcd.del(self.context + '/hosts/' + server); | ||
if (options.all && self.hostsToKeys[server]) { | ||
return Q.all(self.hostsToKeys[server].map(function (key) { | ||
return self.etcd.del(key) | ||
})); | ||
} else { | ||
return self.etcd.del(self.context + '/hosts/' + server + ':' + (options.id ? options.id : self.pid)); | ||
} | ||
}); | ||
@@ -83,0 +111,0 @@ }; |
@@ -25,7 +25,7 @@ var expect = require('chai').expect; | ||
}); | ||
var pid = process.pid; | ||
describe('#servers, #addServer', function () { | ||
it('Should get all servers', function (done) { | ||
var watcher = frodo.etcd.watcher('integration/hosts/done'); | ||
var watcher = frodo.etcd.watcher('integration/hosts/done:' + pid); | ||
frodo.addServer('first').then(function () { | ||
@@ -49,3 +49,3 @@ frodo.addServer('second').then(function () { | ||
it('Should get all servers on init', function (done) { | ||
var watcher = frodo.etcd.watcher('integration/hosts/done'); | ||
var watcher = frodo.etcd.watcher('integration/hosts/done:' + pid); | ||
var otherFrodo; | ||
@@ -73,3 +73,3 @@ frodo.addServer('first').then(function () { | ||
it('Should remove servers', function (done) { | ||
var watcher = frodo.etcd.watcher('integration/hosts/done'); | ||
var watcher = frodo.etcd.watcher('integration/hosts/done:' + pid); | ||
frodo.addServer('first').then(function () { | ||
@@ -94,3 +94,3 @@ frodo.removeServer('first').then(function () { | ||
it('Should handle failed on removal of not existing server', function (done) { | ||
var watcher = frodo.etcd.watcher('integration/hosts/done'); | ||
var watcher = frodo.etcd.watcher('integration/hosts/done:' + pid); | ||
frodo.removeServer('foo').fail(function () { | ||
@@ -110,4 +110,4 @@ frodo.addServer('done'); | ||
it ('Should updated when changing hosts from other server', function (done) { | ||
var watcher = frodo.etcd.watcher('integration/hosts/done'); | ||
it('Should updated when changing hosts from other server', function (done) { | ||
var watcher = frodo.etcd.watcher('integration/hosts/done:' + pid); | ||
var otherFrodo = new Frodo({ context: 'integration' }); | ||
@@ -137,3 +137,46 @@ | ||
it('Should delete all servers with same key', function (done) { | ||
var firstWatcher = frodo.etcd.watcher('integration/hosts/first-done:' + pid); | ||
var secondWatcher = frodo.etcd.watcher('integration/hosts/second-done:' + pid); | ||
var otherFrodo = new Frodo({ context: 'integration' }); | ||
// Adding 2 firsts -> 1 second -> 1 first -> checking that all have been added -> remove all instances of first -> check that only host named second is there. | ||
otherFrodo.ready.then(function () { | ||
return otherFrodo.addServer('first', { id: 1 }); | ||
}).then(function () { | ||
return otherFrodo.addServer('first', { id: 2 }); | ||
}).then(function () { | ||
return otherFrodo.addServer('second'); | ||
}).then(function () { | ||
return otherFrodo.addServer('first', { id: 3 }); | ||
}).then(function () { | ||
return otherFrodo.addServer('first-done'); | ||
}).done(); | ||
firstWatcher.on('change', function () { | ||
frodo.servers().then(function (servers) { | ||
expect(servers[0]).to.equal('first'); | ||
expect(servers[1]).to.equal('first'); | ||
expect(servers[2]).to.equal('second'); | ||
expect(servers[3]).to.equal('first'); | ||
}).then(function () { | ||
return otherFrodo.removeServer('first', { all: true }); | ||
}).then(function () { | ||
return otherFrodo.addServer('second-done'); | ||
}).done(); | ||
}); | ||
secondWatcher.on('change', function () { | ||
return Q.delay(30).then(function () { | ||
return frodo.servers().then(function (servers) { | ||
expect(servers[0]).to.equal('second'); | ||
expect(servers[1]).to.not.equal('first'); | ||
expect(servers[2]).to.not.equal('first'); | ||
otherFrodo.close(); | ||
done(); | ||
}); | ||
}).done(); | ||
}); | ||
}) | ||
}); | ||
}); |
@@ -21,2 +21,3 @@ var expect = require('chai').expect; | ||
}); | ||
var pid = process.pid; | ||
@@ -36,3 +37,3 @@ describe('#servers', function () { | ||
it('Should add a server', function (done) { | ||
mock.expects('set').withArgs('test/hosts/third', 'third').returns(Q()); | ||
mock.expects('set').withArgs('test/hosts/third:' + pid, 'third').returns(Q()); | ||
frodo.addServer('third').then(function () { | ||
@@ -48,3 +49,3 @@ frodo.close(); | ||
it('Should remove a server', function (done) { | ||
mock.expects('del').withArgs('test/hosts/second').returns(Q()); | ||
mock.expects('del').withArgs('test/hosts/second:' + pid).returns(Q()); | ||
frodo.removeServer('second').then(function () { | ||
@@ -51,0 +52,0 @@ frodo.close(); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16740
353