Skip to content

Commit

Permalink
Support redis schema
Browse files Browse the repository at this point in the history
  • Loading branch information
luin committed Oct 24, 2015
1 parent f2284a6 commit 6a3c4fb
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 15 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This file is a manually maintained list of changes for each release. Feel free t

## Master Branch (Unreleased)

* [Cluster] Support redis schema url.
* [Cluster] Support specifying password for each node.
* Add an option for setting connection name. [cgiovanacci](https://github.com/cgiovanacci).
* Switch to the previous db before re-subscribing channels.
Expand Down
42 changes: 28 additions & 14 deletions lib/cluster.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,30 @@ var Command = require('./command');
* @extends [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)
* @extends Commander
*/
function Cluster (startupNodes, options) {
function Cluster(startupNodes, options) {
EventEmitter.call(this);
Commander.call(this);

if (!Array.isArray(startupNodes) || startupNodes.length === 0) {
throw new Error('`startupNodes` should contain at least one node.');
}
this.startupNodes = startupNodes;
this.startupNodes = startupNodes.map(function (node) {
var options = {};
if (typeof node === 'object') {
_.defaults(options, node);
} else if (typeof node === 'string') {
_.defaults(options, utils.parseURL(node));
} else if (typeof node === 'number') {
options.port = node;
} else {
throw new Error('Invalid argument ' + node);
}
if (typeof options.port === 'string') {
options.port = parseInt(options.port, 10);
}
delete options.db;
return options;
});

this.nodes = {};
this.masterNodes = {};
Expand Down Expand Up @@ -162,21 +178,19 @@ Cluster.prototype.createNode = function (port, host) {
retryStrategy: null
}, Redis.defaultOptions);

// Fetch password from startupNodes option
var password;
for (var i = 0; i < this.startupNodes.length; i++) {
var node = this.startupNodes[i];
if (node.port === port && node.host === host) {
password = node.password || null;
break;
}
}
if (typeof password !== 'undefined') {
nodeOpt.password = password;
}
var key = nodeOpt.host + ':' + nodeOpt.port;

if (!this.nodes[key]) {
// Fetch password from startupNodes option
delete nodeOpt.password;
for (var i = 0; i < this.startupNodes.length; i++) {
var node = this.startupNodes[i];
if (node.port === nodeOpt.port && node.host === nodeOpt.host) {
nodeOpt.password = node.password;
break;
}
}

this.nodes[key] = new Redis(_.assign({}, this.options, nodeOpt));

var _this = this;
Expand Down
59 changes: 58 additions & 1 deletion test/functional/cluster.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,30 @@ describe('cluster', function () {
});
});

it('should support url schema', function (done) {
var node = new MockServer(30001);

var cluster = new Redis.Cluster([
'redis://127.0.0.1:30001'
]);

node.once('connect', function () {
cluster.disconnect();
disconnect([node], done);
});
});

it('should support a single port', function (done) {
var node = new MockServer(30001);

var cluster = new Redis.Cluster([30001]);

node.once('connect', function () {
cluster.disconnect();
disconnect([node], done);
});
});

it('should return a promise to be resolved when connected', function (done) {
var slotTable = [
[0, 5460, ['127.0.0.1', 30001]],
Expand Down Expand Up @@ -224,13 +248,46 @@ describe('cluster', function () {
expect(err.message).to.eql(errorMessage);
checkDone();
});
function checkDone () {
function checkDone() {
if (!--pending) {
cluster.disconnect();
disconnect([node1, node2], done);
}
}
});

it('should using the specified password', function (done) {
var node1, node2, node3;
var slotTable = [
[0, 5460, ['127.0.0.1', 30001]],
[5461, 10922, ['127.0.0.1', 30002]],
[10923, 16383, ['127.0.0.1', 30003]]
];
var argvHandler = function (port, argv) {
if (argv[0] === 'cluster' && argv[1] === 'slots') {
return slotTable;
}
if (argv[0] === 'auth') {
var password = argv[1];
if (port === 30001) {
expect(password).to.eql('other password');
} else if (port === 30002) {
throw new Error('30002 got password');
} else if (port === 30003) {
expect(password).to.eql('default password');
disconnect([node1, node2, node3], done);
}
}
};
node1 = new MockServer(30001, argvHandler.bind(null, 30001));
node2 = new MockServer(30002, argvHandler.bind(null, 30002));
node3 = new MockServer(30003, argvHandler.bind(null, 30003));

new Redis.Cluster([
{ host: '127.0.0.1', port: '30001', password: 'other password' },
{ host: '127.0.0.1', port: '30002' }
], { lazyConnect: false, password: 'default password' });
});
});

describe('MOVE', function () {
Expand Down

0 comments on commit 6a3c4fb

Please sign in to comment.