You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-04 15:02:09 +03:00
Remove snack_case and always use camelCase
This commit is contained in:
committed by
Ruben Bridgewater
parent
a86c998a64
commit
28afc33c9a
@@ -2,7 +2,7 @@
|
||||
|
||||
var fs = require('fs');
|
||||
var metrics = require('metrics');
|
||||
// `node diff_multi_bench_output.js beforeBench.txt afterBench.txt`
|
||||
// `node diffMultiBenchOutput.js beforeBench.txt afterBench.txt`
|
||||
var file1 = process.argv[2];
|
||||
var file2 = process.argv[3];
|
||||
|
||||
@@ -17,13 +17,13 @@ if (!file1 || !file2) {
|
||||
return;
|
||||
}
|
||||
|
||||
var before_lines = fs.readFileSync(file1, 'utf8').split('\n');
|
||||
var after_lines = fs.readFileSync(file2, 'utf8').split('\n');
|
||||
var total_ops = new metrics.Histogram.createUniformHistogram();
|
||||
var beforeLines = fs.readFileSync(file1, 'utf8').split('\n');
|
||||
var afterLines = fs.readFileSync(file2, 'utf8').split('\n');
|
||||
var totalOps = new metrics.Histogram.createUniformHistogram();
|
||||
|
||||
console.log('Comparing before,', file1, '(', before_lines.length, 'lines)', 'to after,', file2, '(', after_lines.length, 'lines)');
|
||||
console.log('Comparing before,', file1, '(', beforeLines.length, 'lines)', 'to after,', file2, '(', afterLines.length, 'lines)');
|
||||
|
||||
function is_whitespace (s) {
|
||||
function isWhitespace (s) {
|
||||
return !!s.trim();
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ function pad (input, len, chr, right) {
|
||||
}
|
||||
|
||||
// green if greater than 0, red otherwise
|
||||
function humanize_diff (num, unit, toFixed) {
|
||||
function humanizeDiff (num, unit, toFixed) {
|
||||
unit = unit || '';
|
||||
if (num > 0) {
|
||||
return ' +' + pad(num.toFixed(toFixed || 0) + unit, 7);
|
||||
@@ -52,21 +52,21 @@ function humanize_diff (num, unit, toFixed) {
|
||||
return ' -' + pad(Math.abs(num).toFixed(toFixed || 0) + unit, 7);
|
||||
}
|
||||
|
||||
function command_name (words) {
|
||||
function commandName (words) {
|
||||
var line = words.join(' ');
|
||||
return line.substr(0, line.indexOf(','));
|
||||
}
|
||||
|
||||
before_lines.forEach(function (b, i) {
|
||||
var a = after_lines[i];
|
||||
beforeLines.forEach(function (b, i) {
|
||||
var a = afterLines[i];
|
||||
if (!a || !b || !b.trim() || !a.trim()) {
|
||||
// console.log('#ignored#', '>'+a+'<', '>'+b+'<');
|
||||
return;
|
||||
}
|
||||
var b_words = b.split(' ').filter(is_whitespace);
|
||||
var a_words = a.split(' ').filter(is_whitespace);
|
||||
var bWords = b.split(' ').filter(isWhitespace);
|
||||
var aWords = a.split(' ').filter(isWhitespace);
|
||||
|
||||
var ops = [b_words, a_words].map(function (words) {
|
||||
var ops = [bWords, aWords].map(function (words) {
|
||||
// console.log(words);
|
||||
return words.slice(-2, -1) | 0;
|
||||
}).filter(function (num) {
|
||||
@@ -80,16 +80,16 @@ before_lines.forEach(function (b, i) {
|
||||
var pct = +((delta / ops[0]) * 100);
|
||||
ops[0] = pad(ops[0], 6);
|
||||
ops[1] = pad(ops[1], 6);
|
||||
total_ops.update(delta);
|
||||
delta = humanize_diff(delta);
|
||||
var small_delta = pct < 3 && pct > -3;
|
||||
totalOps.update(delta);
|
||||
delta = humanizeDiff(delta);
|
||||
var smallDelta = pct < 3 && pct > -3;
|
||||
// Let's mark differences above 20% bold
|
||||
var big_delta = pct > 20 || pct < -20 ? ';1' : '';
|
||||
pct = humanize_diff(pct, '', 2) + '%';
|
||||
var str = pad((command_name(a_words) === command_name(b_words) ? command_name(a_words) + ':' : '404:'), 14, false, true) +
|
||||
var bigDelta = pct > 20 || pct < -20 ? ';1' : '';
|
||||
pct = humanizeDiff(pct, '', 2) + '%';
|
||||
var str = pad((commandName(aWords) === commandName(bWords) ? commandName(aWords) + ':' : '404:'), 14, false, true) +
|
||||
(pad(ops.join(' -> '), 15) + ' ops/sec (∆' + delta + pct + ')');
|
||||
str = (small_delta ? '' : (/-[^>]/.test(str) ? '\x1b[31' : '\x1b[32') + big_delta + 'm') + str + '\x1b[0m';
|
||||
str = (smallDelta ? '' : (/-[^>]/.test(str) ? '\x1b[31' : '\x1b[32') + bigDelta + 'm') + str + '\x1b[0m';
|
||||
console.log(str);
|
||||
});
|
||||
|
||||
console.log('Mean difference in ops/sec:', humanize_diff(total_ops.mean(), '', 1));
|
||||
console.log('Mean difference in ops/sec:', humanizeDiff(totalOps.mean(), '', 1));
|
||||
|
@@ -3,7 +3,7 @@
|
||||
var path = require('path');
|
||||
var RedisProcess = require('../test/lib/redis-process');
|
||||
var rp;
|
||||
var client_nr = 0;
|
||||
var clientNr = 0;
|
||||
var redis = require('../index');
|
||||
var totalTime = 0;
|
||||
var metrics = require('metrics');
|
||||
@@ -21,14 +21,14 @@ function returnArg (name, def) {
|
||||
}
|
||||
return def;
|
||||
}
|
||||
var num_clients = returnArg('clients', 1);
|
||||
var run_time = returnArg('time', 2500); // ms
|
||||
var numClients = returnArg('clients', 1);
|
||||
var runTime = returnArg('time', 2500); // ms
|
||||
var pipeline = returnArg('pipeline', 1); // number of concurrent commands
|
||||
var versions_logged = false;
|
||||
var client_options = {
|
||||
var versionsLogged = false;
|
||||
var clientOptions = {
|
||||
path: returnArg('socket') // '/tmp/redis.sock'
|
||||
};
|
||||
var small_str, large_str, small_buf, large_buf, very_large_str, very_large_buf, mget_array;
|
||||
var smallStr, largeStr, smallBuf, largeBuf, veryLargeStr, veryLargeBuf, mgetArray;
|
||||
|
||||
function lpad (input, len, chr) {
|
||||
var str = input.toString();
|
||||
@@ -39,7 +39,7 @@ function lpad (input, len, chr) {
|
||||
return str;
|
||||
}
|
||||
|
||||
metrics.Histogram.prototype.print_line = function () {
|
||||
metrics.Histogram.prototype.printLine = function () {
|
||||
var obj = this.printObj();
|
||||
return lpad((obj.mean / 1e6).toFixed(2), 6) + '/' + lpad((obj.max / 1e6).toFixed(2), 6);
|
||||
};
|
||||
@@ -49,58 +49,58 @@ function Test (args) {
|
||||
this.args.pipeline = +pipeline;
|
||||
this.callback = null;
|
||||
this.clients = [];
|
||||
this.clients_ready = 0;
|
||||
this.commands_sent = 0;
|
||||
this.commands_completed = 0;
|
||||
this.max_pipeline = +pipeline;
|
||||
this.batch_pipeline = this.args.batch || 0;
|
||||
this.client_options = args.client_options || {};
|
||||
this.client_options.connect_timeout = 1000;
|
||||
if (client_options.path) {
|
||||
this.client_options.path = client_options.path;
|
||||
this.clientsReady = 0;
|
||||
this.commandsSent = 0;
|
||||
this.commandsCompleted = 0;
|
||||
this.maxPipeline = +pipeline;
|
||||
this.batchPipeline = this.args.batch || 0;
|
||||
this.clientOptions = args.clientOptions || {};
|
||||
this.clientOptions.connectTimeout = 1000;
|
||||
if (clientOptions.path) {
|
||||
this.clientOptions.path = clientOptions.path;
|
||||
}
|
||||
this.connect_latency = new metrics.Histogram();
|
||||
this.ready_latency = new metrics.Histogram();
|
||||
this.command_latency = new metrics.Histogram();
|
||||
this.connectLatency = new metrics.Histogram();
|
||||
this.readyLatency = new metrics.Histogram();
|
||||
this.commandLatency = new metrics.Histogram();
|
||||
}
|
||||
|
||||
Test.prototype.run = function (callback) {
|
||||
var i;
|
||||
this.callback = callback;
|
||||
for (i = 0; i < num_clients ; i++) {
|
||||
this.new_client(i);
|
||||
for (i = 0; i < numClients ; i++) {
|
||||
this.newClient(i);
|
||||
}
|
||||
};
|
||||
|
||||
Test.prototype.new_client = function (id) {
|
||||
var self = this, new_client;
|
||||
Test.prototype.newClient = function (id) {
|
||||
var self = this, newClient;
|
||||
|
||||
new_client = redis.createClient(this.client_options);
|
||||
new_client.create_time = Date.now();
|
||||
newClient = redis.createClient(this.clientOptions);
|
||||
newClient.createTime = Date.now();
|
||||
|
||||
new_client.on('connect', function () {
|
||||
self.connect_latency.update(Date.now() - new_client.create_time);
|
||||
newClient.on('connect', function () {
|
||||
self.connectLatency.update(Date.now() - newClient.createTime);
|
||||
});
|
||||
|
||||
new_client.on('ready', function () {
|
||||
if (!versions_logged) {
|
||||
newClient.on('ready', function () {
|
||||
if (!versionsLogged) {
|
||||
console.log(
|
||||
'clients: ' + num_clients +
|
||||
'clients: ' + numClients +
|
||||
', NodeJS: ' + process.versions.node +
|
||||
', Redis: ' + new_client.server_info.redis_version +
|
||||
', connected by: ' + (client_options.path ? 'socket' : 'tcp')
|
||||
', Redis: ' + newClient.serverInfo.redis_version +
|
||||
', connected by: ' + (clientOptions.path ? 'socket' : 'tcp')
|
||||
);
|
||||
versions_logged = true;
|
||||
versionsLogged = true;
|
||||
}
|
||||
self.ready_latency.update(Date.now() - new_client.create_time);
|
||||
self.clients_ready++;
|
||||
if (self.clients_ready === self.clients.length) {
|
||||
self.on_clients_ready();
|
||||
self.readyLatency.update(Date.now() - newClient.createTime);
|
||||
self.clientsReady++;
|
||||
if (self.clientsReady === self.clients.length) {
|
||||
self.onClientsReady();
|
||||
}
|
||||
});
|
||||
|
||||
// If no redis server is running, start one
|
||||
new_client.on('error', function (err) {
|
||||
newClient.on('error', function (err) {
|
||||
if (err.code === 'CONNECTION_BROKEN') {
|
||||
throw err;
|
||||
}
|
||||
@@ -109,56 +109,56 @@ Test.prototype.new_client = function (id) {
|
||||
}
|
||||
rp = true;
|
||||
var conf = '../test/conf/redis.conf';
|
||||
RedisProcess.start(function (err, _rp) {
|
||||
RedisProcess.start(function (err, Rp) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
rp = _rp;
|
||||
rp = Rp;
|
||||
}, path.resolve(__dirname, conf));
|
||||
});
|
||||
|
||||
self.clients[id] = new_client;
|
||||
self.clients[id] = newClient;
|
||||
};
|
||||
|
||||
Test.prototype.on_clients_ready = function () {
|
||||
process.stdout.write(lpad(this.args.descr, 13) + ', ' + (this.args.batch ? lpad('batch ' + this.args.batch, 9) : lpad(this.args.pipeline, 9)) + '/' + this.clients_ready + ' ');
|
||||
this.test_start = Date.now();
|
||||
this.fill_pipeline();
|
||||
Test.prototype.onClientsReady = function () {
|
||||
process.stdout.write(lpad(this.args.descr, 13) + ', ' + (this.args.batch ? lpad('batch ' + this.args.batch, 9) : lpad(this.args.pipeline, 9)) + '/' + this.clientsReady + ' ');
|
||||
this.testStart = Date.now();
|
||||
this.fillPipeline();
|
||||
};
|
||||
|
||||
Test.prototype.fill_pipeline = function () {
|
||||
var pipeline = this.commands_sent - this.commands_completed;
|
||||
Test.prototype.fillPipeline = function () {
|
||||
var pipeline = this.commandsSent - this.commandsCompleted;
|
||||
|
||||
if (this.test_start < Date.now() - run_time) {
|
||||
if (this.testStart < Date.now() - runTime) {
|
||||
if (this.ended) {
|
||||
return;
|
||||
}
|
||||
this.ended = true;
|
||||
this.print_stats();
|
||||
this.stop_clients();
|
||||
this.printStats();
|
||||
this.stopClients();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.batch_pipeline) {
|
||||
if (this.batchPipeline) {
|
||||
this.batch();
|
||||
} else {
|
||||
while (pipeline < this.max_pipeline) {
|
||||
this.commands_sent++;
|
||||
while (pipeline < this.maxPipeline) {
|
||||
this.commandsSent++;
|
||||
pipeline++;
|
||||
this.send_next();
|
||||
this.sendNext();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Test.prototype.batch = function () {
|
||||
var self = this,
|
||||
cur_client = client_nr++ % this.clients.length,
|
||||
curClient = clientNr++ % this.clients.length,
|
||||
start = process.hrtime(),
|
||||
i = 0,
|
||||
batch = this.clients[cur_client].batch();
|
||||
batch = this.clients[curClient].batch();
|
||||
|
||||
while (i++ < this.batch_pipeline) {
|
||||
this.commands_sent++;
|
||||
while (i++ < this.batchPipeline) {
|
||||
this.commandsSent++;
|
||||
batch[this.args.command](this.args.args);
|
||||
}
|
||||
|
||||
@@ -166,13 +166,13 @@ Test.prototype.batch = function () {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
self.commands_completed += res.length;
|
||||
self.command_latency.update(process.hrtime(start)[1]);
|
||||
self.fill_pipeline();
|
||||
self.commandsCompleted += res.length;
|
||||
self.commandLatency.update(process.hrtime(start)[1]);
|
||||
self.fillPipeline();
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.stop_clients = function () {
|
||||
Test.prototype.stopClients = function () {
|
||||
var self = this;
|
||||
|
||||
this.clients.forEach(function (client, pos) {
|
||||
@@ -186,69 +186,69 @@ Test.prototype.stop_clients = function () {
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.send_next = function () {
|
||||
Test.prototype.sendNext = function () {
|
||||
var self = this,
|
||||
cur_client = this.commands_sent % this.clients.length,
|
||||
curClient = this.commandsSent % this.clients.length,
|
||||
start = process.hrtime();
|
||||
|
||||
this.clients[cur_client][this.args.command](this.args.args, function (err, res) {
|
||||
this.clients[curClient][this.args.command](this.args.args, function (err, res) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
self.commands_completed++;
|
||||
self.command_latency.update(process.hrtime(start)[1]);
|
||||
self.fill_pipeline();
|
||||
self.commandsCompleted++;
|
||||
self.commandLatency.update(process.hrtime(start)[1]);
|
||||
self.fillPipeline();
|
||||
});
|
||||
};
|
||||
|
||||
Test.prototype.print_stats = function () {
|
||||
var duration = Date.now() - this.test_start;
|
||||
Test.prototype.printStats = function () {
|
||||
var duration = Date.now() - this.testStart;
|
||||
totalTime += duration;
|
||||
|
||||
console.log('avg/max: ' + this.command_latency.print_line() + lpad(duration, 5) + 'ms total, ' +
|
||||
lpad(Math.round(this.commands_completed / (duration / 1000)), 7) + ' ops/sec');
|
||||
console.log('avg/max: ' + this.commandLatency.printLine() + lpad(duration, 5) + 'ms total, ' +
|
||||
lpad(Math.round(this.commandsCompleted / (duration / 1000)), 7) + ' ops/sec');
|
||||
};
|
||||
|
||||
small_str = '1234';
|
||||
small_buf = new Buffer(small_str);
|
||||
large_str = (new Array(4096 + 1).join('-'));
|
||||
large_buf = new Buffer(large_str);
|
||||
very_large_str = (new Array((4 * 1024 * 1024) + 1).join('-'));
|
||||
very_large_buf = new Buffer(very_large_str);
|
||||
mget_array = (new Array(1025)).join('foo_rand000000000001;').split(';');
|
||||
smallStr = '1234';
|
||||
smallBuf = new Buffer(smallStr);
|
||||
largeStr = (new Array(4096 + 1).join('-'));
|
||||
largeBuf = new Buffer(largeStr);
|
||||
veryLargeStr = (new Array((4 * 1024 * 1024) + 1).join('-'));
|
||||
veryLargeBuf = new Buffer(veryLargeStr);
|
||||
mgetArray = (new Array(1025)).join('fooRand000000000001;').split(';');
|
||||
|
||||
tests.push(new Test({descr: 'PING', command: 'ping', args: []}));
|
||||
tests.push(new Test({descr: 'PING', command: 'ping', args: [], batch: 50}));
|
||||
|
||||
tests.push(new Test({descr: 'SET 4B str', command: 'set', args: ['foo_rand000000000000', small_str]}));
|
||||
tests.push(new Test({descr: 'SET 4B str', command: 'set', args: ['foo_rand000000000000', small_str], batch: 50}));
|
||||
tests.push(new Test({descr: 'SET 4B str', command: 'set', args: ['fooRand000000000000', smallStr]}));
|
||||
tests.push(new Test({descr: 'SET 4B str', command: 'set', args: ['fooRand000000000000', smallStr], batch: 50}));
|
||||
|
||||
tests.push(new Test({descr: 'SET 4B buf', command: 'set', args: ['foo_rand000000000000', small_buf]}));
|
||||
tests.push(new Test({descr: 'SET 4B buf', command: 'set', args: ['foo_rand000000000000', small_buf], batch: 50}));
|
||||
tests.push(new Test({descr: 'SET 4B buf', command: 'set', args: ['fooRand000000000000', smallBuf]}));
|
||||
tests.push(new Test({descr: 'SET 4B buf', command: 'set', args: ['fooRand000000000000', smallBuf], batch: 50}));
|
||||
|
||||
tests.push(new Test({descr: 'GET 4B str', command: 'get', args: ['foo_rand000000000000']}));
|
||||
tests.push(new Test({descr: 'GET 4B str', command: 'get', args: ['foo_rand000000000000'], batch: 50}));
|
||||
tests.push(new Test({descr: 'GET 4B str', command: 'get', args: ['fooRand000000000000']}));
|
||||
tests.push(new Test({descr: 'GET 4B str', command: 'get', args: ['fooRand000000000000'], batch: 50}));
|
||||
|
||||
tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['foo_rand000000000000'], client_options: { return_buffers: true} }));
|
||||
tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['foo_rand000000000000'], batch: 50, client_options: { return_buffers: true} }));
|
||||
tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['fooRand000000000000'], clientOptions: { returnBuffers: true} }));
|
||||
tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['fooRand000000000000'], batch: 50, clientOptions: { returnBuffers: true} }));
|
||||
|
||||
tests.push(new Test({descr: 'SET 4KiB str', command: 'set', args: ['foo_rand000000000001', large_str]}));
|
||||
tests.push(new Test({descr: 'SET 4KiB str', command: 'set', args: ['foo_rand000000000001', large_str], batch: 50}));
|
||||
tests.push(new Test({descr: 'SET 4KiB str', command: 'set', args: ['fooRand000000000001', largeStr]}));
|
||||
tests.push(new Test({descr: 'SET 4KiB str', command: 'set', args: ['fooRand000000000001', largeStr], batch: 50}));
|
||||
|
||||
tests.push(new Test({descr: 'SET 4KiB buf', command: 'set', args: ['foo_rand000000000001', large_buf]}));
|
||||
tests.push(new Test({descr: 'SET 4KiB buf', command: 'set', args: ['foo_rand000000000001', large_buf], batch: 50}));
|
||||
tests.push(new Test({descr: 'SET 4KiB buf', command: 'set', args: ['fooRand000000000001', largeBuf]}));
|
||||
tests.push(new Test({descr: 'SET 4KiB buf', command: 'set', args: ['fooRand000000000001', largeBuf], batch: 50}));
|
||||
|
||||
tests.push(new Test({descr: 'GET 4KiB str', command: 'get', args: ['foo_rand000000000001']}));
|
||||
tests.push(new Test({descr: 'GET 4KiB str', command: 'get', args: ['foo_rand000000000001'], batch: 50}));
|
||||
tests.push(new Test({descr: 'GET 4KiB str', command: 'get', args: ['fooRand000000000001']}));
|
||||
tests.push(new Test({descr: 'GET 4KiB str', command: 'get', args: ['fooRand000000000001'], batch: 50}));
|
||||
|
||||
tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['foo_rand000000000001'], client_options: { return_buffers: true} }));
|
||||
tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['foo_rand000000000001'], batch: 50, client_options: { return_buffers: true} }));
|
||||
tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['fooRand000000000001'], clientOptions: { returnBuffers: true} }));
|
||||
tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['fooRand000000000001'], batch: 50, clientOptions: { returnBuffers: true} }));
|
||||
|
||||
tests.push(new Test({descr: 'INCR', command: 'incr', args: ['counter_rand000000000000']}));
|
||||
tests.push(new Test({descr: 'INCR', command: 'incr', args: ['counter_rand000000000000'], batch: 50}));
|
||||
tests.push(new Test({descr: 'INCR', command: 'incr', args: ['counterRand000000000000']}));
|
||||
tests.push(new Test({descr: 'INCR', command: 'incr', args: ['counterRand000000000000'], batch: 50}));
|
||||
|
||||
tests.push(new Test({descr: 'LPUSH', command: 'lpush', args: ['mylist', small_str]}));
|
||||
tests.push(new Test({descr: 'LPUSH', command: 'lpush', args: ['mylist', small_str], batch: 50}));
|
||||
tests.push(new Test({descr: 'LPUSH', command: 'lpush', args: ['mylist', smallStr]}));
|
||||
tests.push(new Test({descr: 'LPUSH', command: 'lpush', args: ['mylist', smallStr], batch: 50}));
|
||||
|
||||
tests.push(new Test({descr: 'LRANGE 10', command: 'lrange', args: ['mylist', '0', '9']}));
|
||||
tests.push(new Test({descr: 'LRANGE 10', command: 'lrange', args: ['mylist', '0', '9'], batch: 50}));
|
||||
@@ -256,23 +256,23 @@ tests.push(new Test({descr: 'LRANGE 10', command: 'lrange', args: ['mylist', '0'
|
||||
tests.push(new Test({descr: 'LRANGE 100', command: 'lrange', args: ['mylist', '0', '99']}));
|
||||
tests.push(new Test({descr: 'LRANGE 100', command: 'lrange', args: ['mylist', '0', '99'], batch: 50}));
|
||||
|
||||
tests.push(new Test({descr: 'SET 4MiB str', command: 'set', args: ['foo_rand000000000002', very_large_str]}));
|
||||
tests.push(new Test({descr: 'SET 4MiB str', command: 'set', args: ['foo_rand000000000002', very_large_str], batch: 20}));
|
||||
tests.push(new Test({descr: 'SET 4MiB str', command: 'set', args: ['fooRand000000000002', veryLargeStr]}));
|
||||
tests.push(new Test({descr: 'SET 4MiB str', command: 'set', args: ['fooRand000000000002', veryLargeStr], batch: 20}));
|
||||
|
||||
tests.push(new Test({descr: 'SET 4MiB buf', command: 'set', args: ['foo_rand000000000002', very_large_buf]}));
|
||||
tests.push(new Test({descr: 'SET 4MiB buf', command: 'set', args: ['foo_rand000000000002', very_large_buf], batch: 20}));
|
||||
tests.push(new Test({descr: 'SET 4MiB buf', command: 'set', args: ['fooRand000000000002', veryLargeBuf]}));
|
||||
tests.push(new Test({descr: 'SET 4MiB buf', command: 'set', args: ['fooRand000000000002', veryLargeBuf], batch: 20}));
|
||||
|
||||
tests.push(new Test({descr: 'GET 4MiB str', command: 'get', args: ['foo_rand000000000002']}));
|
||||
tests.push(new Test({descr: 'GET 4MiB str', command: 'get', args: ['foo_rand000000000002'], batch: 20}));
|
||||
tests.push(new Test({descr: 'GET 4MiB str', command: 'get', args: ['fooRand000000000002']}));
|
||||
tests.push(new Test({descr: 'GET 4MiB str', command: 'get', args: ['fooRand000000000002'], batch: 20}));
|
||||
|
||||
tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['foo_rand000000000002'], client_options: { return_buffers: true} }));
|
||||
tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['foo_rand000000000002'], batch: 20, client_options: { return_buffers: true} }));
|
||||
tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['fooRand000000000002'], clientOptions: { returnBuffers: true} }));
|
||||
tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['fooRand000000000002'], batch: 20, clientOptions: { returnBuffers: true} }));
|
||||
|
||||
tests.push(new Test({descr: 'MGET 4MiB str', command: 'mget', args: mget_array}));
|
||||
tests.push(new Test({descr: 'MGET 4MiB str', command: 'mget', args: mget_array, batch: 20}));
|
||||
tests.push(new Test({descr: 'MGET 4MiB str', command: 'mget', args: mgetArray}));
|
||||
tests.push(new Test({descr: 'MGET 4MiB str', command: 'mget', args: mgetArray, batch: 20}));
|
||||
|
||||
tests.push(new Test({descr: 'MGET 4MiB buf', command: 'mget', args: mget_array, client_options: { return_buffers: true} }));
|
||||
tests.push(new Test({descr: 'MGET 4MiB buf', command: 'mget', args: mget_array, batch: 20, client_options: { return_buffers: true} }));
|
||||
tests.push(new Test({descr: 'MGET 4MiB buf', command: 'mget', args: mgetArray, clientOptions: { returnBuffers: true} }));
|
||||
tests.push(new Test({descr: 'MGET 4MiB buf', command: 'mget', args: mgetArray, batch: 20, clientOptions: { returnBuffers: true} }));
|
||||
|
||||
function next () {
|
||||
var test = tests.shift();
|
||||
|
@@ -6,7 +6,7 @@ var client = redis.createClient();
|
||||
// Extend the RedisClient prototype to add a custom method
|
||||
// This one converts the results from 'INFO' into a JavaScript Object
|
||||
|
||||
redis.RedisClient.prototype.parse_info = function (callback) {
|
||||
redis.RedisClient.prototype.parseInfo = function (callback) {
|
||||
this.info(function (err, res) {
|
||||
var lines = res.toString().split('\r\n').sort();
|
||||
var obj = {};
|
||||
@@ -20,7 +20,7 @@ redis.RedisClient.prototype.parse_info = function (callback) {
|
||||
});
|
||||
};
|
||||
|
||||
client.parse_info(function (info) {
|
||||
client.parseInfo(function (info) {
|
||||
console.dir(info);
|
||||
client.quit();
|
||||
});
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
var redis = require('redis');
|
||||
var client = redis.createClient({
|
||||
return_buffers: true
|
||||
returnBuffers: true
|
||||
});
|
||||
var fs = require('fs');
|
||||
var assert = require('assert');
|
||||
|
@@ -2,14 +2,14 @@
|
||||
|
||||
var redis = require('redis');
|
||||
var client = redis.createClient();
|
||||
var set_size = 20;
|
||||
var setSize = 20;
|
||||
|
||||
client.sadd('bigset', 'a member');
|
||||
client.sadd('bigset', 'another member');
|
||||
|
||||
while (set_size > 0) {
|
||||
client.sadd('bigset', 'member ' + set_size);
|
||||
set_size -= 1;
|
||||
while (setSize > 0) {
|
||||
client.sadd('bigset', 'member ' + setSize);
|
||||
setSize -= 1;
|
||||
}
|
||||
|
||||
// multi chain with an individual callback
|
||||
|
@@ -5,7 +5,7 @@ var client1 = redis.createClient();
|
||||
var client2 = redis.createClient();
|
||||
var client3 = redis.createClient();
|
||||
var client4 = redis.createClient();
|
||||
var msg_count = 0;
|
||||
var msgCount = 0;
|
||||
|
||||
client1.on('psubscribe', function (pattern, count) {
|
||||
console.log('client1 psubscribed to ' + pattern + ', ' + count + ' total subscriptions');
|
||||
@@ -24,8 +24,8 @@ client1.on('punsubscribe', function (pattern, count) {
|
||||
|
||||
client1.on('pmessage', function (pattern, channel, message) {
|
||||
console.log('(' + pattern + ') client1 received message on ' + channel + ': ' + message);
|
||||
msg_count += 1;
|
||||
if (msg_count === 3) {
|
||||
msgCount += 1;
|
||||
if (msgCount === 3) {
|
||||
client1.punsubscribe();
|
||||
}
|
||||
});
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
var redis = require('redis');
|
||||
var client1 = redis.createClient();
|
||||
var msg_count = 0;
|
||||
var msgCount = 0;
|
||||
var client2 = redis.createClient();
|
||||
|
||||
// Most clients probably don't do much on 'subscribe'. This example uses it to coordinate things within one program.
|
||||
@@ -25,8 +25,8 @@ client1.on('unsubscribe', function (channel, count) {
|
||||
|
||||
client1.on('message', function (channel, message) {
|
||||
console.log('client1 channel ' + channel + ': ' + message);
|
||||
msg_count += 1;
|
||||
if (msg_count === 3) {
|
||||
msgCount += 1;
|
||||
if (msgCount === 3) {
|
||||
client1.unsubscribe();
|
||||
}
|
||||
});
|
||||
|
@@ -3,14 +3,14 @@
|
||||
var client = require('redis').createClient();
|
||||
|
||||
// build a map of all keys and their types
|
||||
client.keys('*', function (err, all_keys) {
|
||||
var key_types = {};
|
||||
client.keys('*', function (err, allKeys) {
|
||||
var keyTypes = {};
|
||||
|
||||
all_keys.forEach(function (key, pos) { // use second arg of forEach to get pos
|
||||
allKeys.forEach(function (key, pos) { // use second arg of forEach to get pos
|
||||
client.type(key, function (err, type) {
|
||||
key_types[key] = type;
|
||||
if (pos === all_keys.length - 1) { // callbacks all run in order
|
||||
console.dir(key_types);
|
||||
keyTypes[key] = type;
|
||||
if (pos === allKeys.length - 1) { // callbacks all run in order
|
||||
console.dir(keyTypes);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@@ -3,27 +3,27 @@
|
||||
// A simple web server that generates dyanmic content based on responses from Redis
|
||||
|
||||
var http = require('http');
|
||||
var redis_client = require('redis').createClient();
|
||||
var redisClient = require('redis').createClient();
|
||||
|
||||
http.createServer(function (request, response) { // The server
|
||||
response.writeHead(200, {
|
||||
'Content-Type': 'text/plain'
|
||||
});
|
||||
|
||||
var redis_info, total_requests;
|
||||
var redisInfo, totalRequests;
|
||||
|
||||
redis_client.info(function (err, reply) {
|
||||
redis_info = reply; // stash response in outer scope
|
||||
redisClient.info(function (err, reply) {
|
||||
redisInfo = reply; // stash response in outer scope
|
||||
});
|
||||
redis_client.incr('requests', function (err, reply) {
|
||||
total_requests = reply; // stash response in outer scope
|
||||
redisClient.incr('requests', function (err, reply) {
|
||||
totalRequests = reply; // stash response in outer scope
|
||||
});
|
||||
redis_client.hincrby('ip', request.connection.remoteAddress, 1);
|
||||
redis_client.hgetall('ip', function (err, reply) {
|
||||
redisClient.hincrby('ip', request.connection.remoteAddress, 1);
|
||||
redisClient.hgetall('ip', function (err, reply) {
|
||||
// This is the last reply, so all of the previous replies must have completed already
|
||||
response.write('This page was generated after talking to redis.\n\n' +
|
||||
'Redis info:\n' + redis_info + '\n' +
|
||||
'Total requests: ' + total_requests + '\n\n' +
|
||||
'Redis info:\n' + redisInfo + '\n' +
|
||||
'Total requests: ' + totalRequests + '\n\n' +
|
||||
'IP count: \n');
|
||||
Object.keys(reply).forEach(function (ip) {
|
||||
response.write(' ' + ip + ': ' + reply[ip] + '\n');
|
||||
|
@@ -2,12 +2,12 @@
|
||||
|
||||
var betterStackTraces = /development/i.test(process.env.NODE_ENV) || /\bredis\b/i.test(process.env.NODE_DEBUG);
|
||||
|
||||
function Command (command, args, callback, call_on_write) {
|
||||
function Command (command, args, callback, callOnWrite) {
|
||||
this.command = command;
|
||||
this.args = args;
|
||||
this.buffer_args = false;
|
||||
this.bufferArgs = false;
|
||||
this.callback = callback;
|
||||
this.call_on_write = call_on_write;
|
||||
this.callOnWrite = callOnWrite;
|
||||
if (betterStackTraces) {
|
||||
this.error = new Error();
|
||||
}
|
||||
|
@@ -59,7 +59,7 @@ commands.list.forEach(function (command) {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
return this.internal_send_command(new Command(command, arr, callback));
|
||||
return this.internalSendCommand(new Command(command, arr, callback));
|
||||
};
|
||||
if (changeFunctionName) {
|
||||
Object.defineProperty(RedisClient.prototype[command], 'name', {
|
||||
|
@@ -3,27 +3,28 @@
|
||||
var utils = require('./utils');
|
||||
var URL = require('url');
|
||||
|
||||
module.exports = function createClient (port_arg, host_arg, options) {
|
||||
module.exports = function createClient (portArg, hostArg, options) {
|
||||
|
||||
if (typeof port_arg === 'number' || typeof port_arg === 'string' && /^\d+$/.test(port_arg)) {
|
||||
if (typeof portArg === 'number' || typeof portArg === 'string' && /^\d+$/.test(portArg)) {
|
||||
|
||||
var host;
|
||||
if (typeof host_arg === 'string') {
|
||||
host = host_arg;
|
||||
if (typeof hostArg === 'string') {
|
||||
host = hostArg;
|
||||
} else {
|
||||
if (options && host_arg) {
|
||||
if (options && hostArg) {
|
||||
throw new TypeError('Unknown type of connection in createClient()');
|
||||
}
|
||||
options = options || host_arg;
|
||||
options = options || hostArg;
|
||||
}
|
||||
options = utils.clone(options);
|
||||
options.host = host || options.host;
|
||||
options.port = port_arg;
|
||||
options.port = portArg;
|
||||
|
||||
} else if (typeof port_arg === 'string' || port_arg && port_arg.url) {
|
||||
} else if (typeof portArg === 'string' || portArg && portArg.url) {
|
||||
|
||||
options = utils.clone(port_arg.url ? port_arg : host_arg || options);
|
||||
var parsed = URL.parse(port_arg.url || port_arg, true, true);
|
||||
options = utils.clone(portArg.url ? portArg : hostArg || options);
|
||||
|
||||
var parsed = URL.parse(portArg.url || portArg, true, true);
|
||||
|
||||
// [redis:]//[[user][:password]@][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]
|
||||
if (parsed.slashes) { // We require slashes
|
||||
@@ -31,7 +32,7 @@ module.exports = function createClient (port_arg, host_arg, options) {
|
||||
options.password = parsed.auth.split(':')[1];
|
||||
}
|
||||
if (parsed.protocol && parsed.protocol !== 'redis:') {
|
||||
console.warn('node_redis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!');
|
||||
console.warn('nodeRedis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!');
|
||||
}
|
||||
if (parsed.pathname && parsed.pathname !== '/') {
|
||||
options.db = parsed.pathname.substr(1);
|
||||
@@ -48,7 +49,7 @@ module.exports = function createClient (port_arg, host_arg, options) {
|
||||
// If options are passed twice, only the parsed options will be used
|
||||
if (elem in options) {
|
||||
if (options[elem] === parsed.query[elem]) {
|
||||
console.warn('node_redis: WARNING: You passed the ' + elem + ' option twice!');
|
||||
console.warn('nodeRedis: WARNING: You passed the ' + elem + ' option twice!');
|
||||
} else {
|
||||
throw new RangeError('The ' + elem + ' option is added twice and does not match');
|
||||
}
|
||||
@@ -59,14 +60,14 @@ module.exports = function createClient (port_arg, host_arg, options) {
|
||||
} else if (parsed.hostname) {
|
||||
throw new RangeError('The redis url must begin with slashes "//" or contain slashes after the redis protocol');
|
||||
} else {
|
||||
options.path = port_arg;
|
||||
options.path = portArg;
|
||||
}
|
||||
|
||||
} else if (typeof port_arg === 'object' || port_arg === undefined) {
|
||||
options = utils.clone(port_arg || options);
|
||||
options.host = options.host || host_arg;
|
||||
} else if (typeof portArg === 'object' || portArg === undefined) {
|
||||
options = utils.clone(portArg || options);
|
||||
options.host = options.host || hostArg;
|
||||
|
||||
if (port_arg && arguments.length !== 1) {
|
||||
if (portArg && arguments.length !== 1) {
|
||||
throw new TypeError('To many arguments passed to createClient. Please only pass the options object');
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
var index = require('../');
|
||||
|
||||
function debug () {
|
||||
if (index.debug_mode) {
|
||||
if (index.debugMode) {
|
||||
console.error.apply(null, arguments);
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ All documented and exposed API belongs in here
|
||||
**********************************************/
|
||||
|
||||
// Redirect calls to the appropriate function and use to send arbitrary / not supported commands
|
||||
RedisClient.prototype.send_command = RedisClient.prototype.sendCommand = function (command, args, callback) {
|
||||
RedisClient.prototype.sendCommand = function (command, args, callback) {
|
||||
// Throw to fail early instead of relying in order in this case
|
||||
if (typeof command !== 'string') {
|
||||
throw new TypeError('Wrong input type "' + (command !== null && command !== undefined ? command.constructor.name : command) + '" for command name');
|
||||
@@ -37,7 +37,7 @@ RedisClient.prototype.send_command = RedisClient.prototype.sendCommand = functio
|
||||
// but this might change from time to time and at the moment there's no good way to distinguishe them
|
||||
// from each other, so let's just do it do it this way for the time being
|
||||
if (command === 'multi' || typeof this[command] !== 'function') {
|
||||
return this.internal_send_command(new Command(command, args, callback));
|
||||
return this.internalSendCommand(new Command(command, args, callback));
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
args = args.concat([callback]); // Prevent manipulating the input array
|
||||
@@ -48,20 +48,20 @@ RedisClient.prototype.send_command = RedisClient.prototype.sendCommand = functio
|
||||
RedisClient.prototype.end = function (flush) {
|
||||
// Flush queue if wanted
|
||||
if (flush) {
|
||||
this.flush_and_error({
|
||||
this.flushAndError({
|
||||
message: 'Connection forcefully ended and command aborted.',
|
||||
code: 'NR_CLOSED'
|
||||
});
|
||||
} else if (arguments.length === 0) {
|
||||
this.warn(
|
||||
'Using .end() without the flush parameter is deprecated and throws from v.3.0.0 on.\n' +
|
||||
'Please check the doku (https://github.com/NodeRedis/node_redis) and explictly use flush.'
|
||||
'Please check the doku (https://github.com/NodeRedis/nodeRedis) and explictly use flush.'
|
||||
);
|
||||
}
|
||||
// Clear retry_timer
|
||||
if (this.retry_timer) {
|
||||
clearTimeout(this.retry_timer);
|
||||
this.retry_timer = null;
|
||||
// Clear retryTimer
|
||||
if (this.retryTimer) {
|
||||
clearTimeout(this.retryTimer);
|
||||
this.retryTimer = null;
|
||||
}
|
||||
this.stream.removeAllListeners();
|
||||
this.stream.on('error', noop);
|
||||
@@ -88,24 +88,24 @@ RedisClient.prototype.duplicate = function (options, callback) {
|
||||
callback = options;
|
||||
options = null;
|
||||
}
|
||||
var existing_options = utils.clone(this.options);
|
||||
var existingOptions = utils.clone(this.options);
|
||||
options = utils.clone(options);
|
||||
for (var elem in options) {
|
||||
existing_options[elem] = options[elem];
|
||||
existingOptions[elem] = options[elem];
|
||||
}
|
||||
var client = new RedisClient(existing_options);
|
||||
client.selected_db = this.selected_db;
|
||||
var client = new RedisClient(existingOptions);
|
||||
client.selectedDb = this.selectedDb;
|
||||
if (typeof callback === 'function') {
|
||||
var ready_listener = function () {
|
||||
var readyListener = function () {
|
||||
callback(null, client);
|
||||
client.removeAllListeners(error_listener);
|
||||
client.removeAllListeners(errorListener);
|
||||
};
|
||||
var error_listener = function (err) {
|
||||
var errorListener = function (err) {
|
||||
callback(err);
|
||||
client.end(true);
|
||||
};
|
||||
client.once('ready', ready_listener);
|
||||
client.once('error', error_listener);
|
||||
client.once('ready', readyListener);
|
||||
client.once('error', errorListener);
|
||||
return;
|
||||
}
|
||||
return client;
|
||||
|
@@ -4,7 +4,7 @@ var utils = require('./utils');
|
||||
var debug = require('./debug');
|
||||
var Multi = require('./multi');
|
||||
var Command = require('./command');
|
||||
var no_password_is_set = /no password is set/;
|
||||
var noPasswordIsSet = /no password is set/;
|
||||
var loading = /LOADING/;
|
||||
var RedisClient = require('../').RedisClient;
|
||||
|
||||
@@ -14,7 +14,7 @@ var RedisClient = require('../').RedisClient;
|
||||
The callback may be hooked as needed. The same does not apply to the rest of the function.
|
||||
State should not be set outside of the callback if not absolutly necessary.
|
||||
This is important to make sure it works the same as single command or in a multi context.
|
||||
To make sure everything works with the offline queue use the "call_on_write" function.
|
||||
To make sure everything works with the offline queue use the "callOnWrite" function.
|
||||
This is going to be executed while writing to the stream.
|
||||
|
||||
TODO: Implement individal command generation as soon as possible to prevent divergent code
|
||||
@@ -23,7 +23,7 @@ var RedisClient = require('../').RedisClient;
|
||||
|
||||
RedisClient.prototype.multi = RedisClient.prototype.MULTI = function multi (args) {
|
||||
var multi = new Multi(this, args);
|
||||
multi.exec = multi.EXEC = multi.exec_transaction;
|
||||
multi.exec = multi.EXEC = multi.execTransaction;
|
||||
return multi;
|
||||
};
|
||||
|
||||
@@ -32,45 +32,45 @@ RedisClient.prototype.batch = RedisClient.prototype.BATCH = function batch (args
|
||||
return new Multi(this, args);
|
||||
};
|
||||
|
||||
function select_callback (self, db, callback) {
|
||||
function selectCallback (self, db, callback) {
|
||||
return function (err, res) {
|
||||
if (err === null) {
|
||||
// Store db in this.select_db to restore it on reconnect
|
||||
self.selected_db = db;
|
||||
// Store db in this.selectDb to restore it on reconnect
|
||||
self.selectedDb = db;
|
||||
}
|
||||
utils.callback_or_emit(self, callback, err, res);
|
||||
utils.callbackOrEmit(self, callback, err, res);
|
||||
};
|
||||
}
|
||||
|
||||
RedisClient.prototype.select = RedisClient.prototype.SELECT = function select (db, callback) {
|
||||
return this.internal_send_command(new Command('select', [db], select_callback(this, db, callback)));
|
||||
return this.internalSendCommand(new Command('select', [db], selectCallback(this, db, callback)));
|
||||
};
|
||||
|
||||
Multi.prototype.select = Multi.prototype.SELECT = function select (db, callback) {
|
||||
this.queue.push(new Command('select', [db], select_callback(this._client, db, callback)));
|
||||
this.queue.push(new Command('select', [db], selectCallback(this._client, db, callback)));
|
||||
return this;
|
||||
};
|
||||
|
||||
RedisClient.prototype.monitor = RedisClient.prototype.MONITOR = function monitor (callback) {
|
||||
// Use a individual command, as this is a special case that does not has to be checked for any other command
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
var callOnWrite = function () {
|
||||
// Activating monitor mode has to happen before Redis returned the callback. The monitor result is returned first.
|
||||
// Therefore we expect the command to be properly processed. If this is not the case, it's not an issue either.
|
||||
self.monitoring = true;
|
||||
};
|
||||
return this.internal_send_command(new Command('monitor', [], callback, call_on_write));
|
||||
return this.internalSendCommand(new Command('monitor', [], callback, callOnWrite));
|
||||
};
|
||||
|
||||
// Only works with batch, not in a transaction
|
||||
Multi.prototype.monitor = Multi.prototype.MONITOR = function monitor (callback) {
|
||||
// Use a individual command, as this is a special case that does not has to be checked for any other command
|
||||
if (this.exec !== this.exec_transaction) {
|
||||
if (this.exec !== this.execTransaction) {
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
var callOnWrite = function () {
|
||||
self._client.monitoring = true;
|
||||
};
|
||||
this.queue.push(new Command('monitor', [], callback, call_on_write));
|
||||
this.queue.push(new Command('monitor', [], callback, callOnWrite));
|
||||
return this;
|
||||
}
|
||||
// Set multi monitoring to indicate the exec that it should abort
|
||||
@@ -79,7 +79,7 @@ Multi.prototype.monitor = Multi.prototype.MONITOR = function monitor (callback)
|
||||
return this;
|
||||
};
|
||||
|
||||
function quit_callback (self, callback) {
|
||||
function quitCallback (self, callback) {
|
||||
return function (err, res) {
|
||||
if (err && err.code === 'NR_CLOSED') {
|
||||
// Pretent the quit command worked properly in this case.
|
||||
@@ -90,7 +90,7 @@ function quit_callback (self, callback) {
|
||||
err = null;
|
||||
res = 'OK';
|
||||
}
|
||||
utils.callback_or_emit(self, callback, err, res);
|
||||
utils.callbackOrEmit(self, callback, err, res);
|
||||
if (self.stream.writable) {
|
||||
// If the socket is still alive, kill it. This could happen if quit got a NR_CLOSED error code
|
||||
self.stream.destroy();
|
||||
@@ -101,40 +101,40 @@ function quit_callback (self, callback) {
|
||||
RedisClient.prototype.QUIT = RedisClient.prototype.quit = function quit (callback) {
|
||||
// TODO: Consider this for v.3
|
||||
// Allow the quit command to be fired as soon as possible to prevent it landing in the offline queue.
|
||||
// this.ready = this.offline_queue.length === 0;
|
||||
var backpressure_indicator = this.internal_send_command(new Command('quit', [], quit_callback(this, callback)));
|
||||
// this.ready = this.offlineQueue.length === 0;
|
||||
var backpressureIndicator = this.internalSendCommand(new Command('quit', [], quitCallback(this, callback)));
|
||||
// Calling quit should always end the connection, no matter if there's a connection or not
|
||||
this.closing = true;
|
||||
this.ready = false;
|
||||
return backpressure_indicator;
|
||||
return backpressureIndicator;
|
||||
};
|
||||
|
||||
// Only works with batch, not in a transaction
|
||||
Multi.prototype.QUIT = Multi.prototype.quit = function quit (callback) {
|
||||
var self = this._client;
|
||||
var call_on_write = function () {
|
||||
var callOnWrite = function () {
|
||||
// If called in a multi context, we expect redis is available
|
||||
self.closing = true;
|
||||
self.ready = false;
|
||||
};
|
||||
this.queue.push(new Command('quit', [], quit_callback(self, callback), call_on_write));
|
||||
this.queue.push(new Command('quit', [], quitCallback(self, callback), callOnWrite));
|
||||
return this;
|
||||
};
|
||||
|
||||
function info_callback (self, callback) {
|
||||
function infoCallback (self, callback) {
|
||||
return function (err, res) {
|
||||
if (res) {
|
||||
var obj = {};
|
||||
var lines = res.toString().split('\r\n');
|
||||
var line, parts, sub_parts;
|
||||
var line, parts, subParts;
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
parts = lines[i].split(':');
|
||||
if (parts[1]) {
|
||||
if (parts[0].indexOf('db') === 0) {
|
||||
sub_parts = parts[1].split(',');
|
||||
subParts = parts[1].split(',');
|
||||
obj[parts[0]] = {};
|
||||
while (line = sub_parts.pop()) {
|
||||
while (line = subParts.pop()) {
|
||||
line = line.split('=');
|
||||
obj[parts[0]][line[0]] = +line[1];
|
||||
}
|
||||
@@ -150,15 +150,15 @@ function info_callback (self, callback) {
|
||||
});
|
||||
}
|
||||
// Expose info key/vals to users
|
||||
self.server_info = obj;
|
||||
self.serverInfo = obj;
|
||||
} else {
|
||||
self.server_info = {};
|
||||
self.serverInfo = {};
|
||||
}
|
||||
utils.callback_or_emit(self, callback, err, res);
|
||||
utils.callbackOrEmit(self, callback, err, res);
|
||||
};
|
||||
}
|
||||
|
||||
// Store info in this.server_info after each call
|
||||
// Store info in this.serverInfo after each call
|
||||
RedisClient.prototype.info = RedisClient.prototype.INFO = function info (section, callback) {
|
||||
var args = [];
|
||||
if (typeof section === 'function') {
|
||||
@@ -166,7 +166,7 @@ RedisClient.prototype.info = RedisClient.prototype.INFO = function info (section
|
||||
} else if (section !== undefined) {
|
||||
args = Array.isArray(section) ? section : [section];
|
||||
}
|
||||
return this.internal_send_command(new Command('info', args, info_callback(this, callback)));
|
||||
return this.internalSendCommand(new Command('info', args, infoCallback(this, callback)));
|
||||
};
|
||||
|
||||
Multi.prototype.info = Multi.prototype.INFO = function info (section, callback) {
|
||||
@@ -176,14 +176,14 @@ Multi.prototype.info = Multi.prototype.INFO = function info (section, callback)
|
||||
} else if (section !== undefined) {
|
||||
args = Array.isArray(section) ? section : [section];
|
||||
}
|
||||
this.queue.push(new Command('info', args, info_callback(this._client, callback)));
|
||||
this.queue.push(new Command('info', args, infoCallback(this._client, callback)));
|
||||
return this;
|
||||
};
|
||||
|
||||
function auth_callback (self, pass, callback) {
|
||||
function authCallback (self, pass, callback) {
|
||||
return function (err, res) {
|
||||
if (err) {
|
||||
if (no_password_is_set.test(err.message)) {
|
||||
if (noPasswordIsSet.test(err.message)) {
|
||||
self.warn('Warning: Redis server does not require a password, but a password was supplied.');
|
||||
err = null;
|
||||
res = 'OK';
|
||||
@@ -196,29 +196,29 @@ function auth_callback (self, pass, callback) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
utils.callback_or_emit(self, callback, err, res);
|
||||
utils.callbackOrEmit(self, callback, err, res);
|
||||
};
|
||||
}
|
||||
|
||||
RedisClient.prototype.auth = RedisClient.prototype.AUTH = function auth (pass, callback) {
|
||||
debug('Sending auth to ' + this.address + ' id ' + this.connection_id);
|
||||
debug('Sending auth to ' + this.address + ' id ' + this.connectionId);
|
||||
|
||||
// Stash auth for connect and reconnect.
|
||||
this.auth_pass = pass;
|
||||
this.authPass = pass;
|
||||
var ready = this.ready;
|
||||
this.ready = ready || this.offline_queue.length === 0;
|
||||
var tmp = this.internal_send_command(new Command('auth', [pass], auth_callback(this, pass, callback)));
|
||||
this.ready = ready || this.offlineQueue.length === 0;
|
||||
var tmp = this.internalSendCommand(new Command('auth', [pass], authCallback(this, pass, callback)));
|
||||
this.ready = ready;
|
||||
return tmp;
|
||||
};
|
||||
|
||||
// Only works with batch, not in a transaction
|
||||
Multi.prototype.auth = Multi.prototype.AUTH = function auth (pass, callback) {
|
||||
debug('Sending auth to ' + this.address + ' id ' + this.connection_id);
|
||||
debug('Sending auth to ' + this.address + ' id ' + this.connectionId);
|
||||
|
||||
// Stash auth for connect and reconnect.
|
||||
this.auth_pass = pass;
|
||||
this.queue.push(new Command('auth', [pass], auth_callback(this._client, callback)));
|
||||
this.authPass = pass;
|
||||
this.queue.push(new Command('auth', [pass], authCallback(this._client, callback)));
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -253,18 +253,18 @@ RedisClient.prototype.client = RedisClient.prototype.CLIENT = function client ()
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
var call_on_write = undefined;
|
||||
var callOnWrite = undefined;
|
||||
// CLIENT REPLY ON|OFF|SKIP
|
||||
/* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */
|
||||
if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') {
|
||||
var reply_on_off = arr[1].toString().toUpperCase();
|
||||
if (reply_on_off === 'ON' || reply_on_off === 'OFF' || reply_on_off === 'SKIP') {
|
||||
call_on_write = function () {
|
||||
self.reply = reply_on_off;
|
||||
var replyOnOff = arr[1].toString().toUpperCase();
|
||||
if (replyOnOff === 'ON' || replyOnOff === 'OFF' || replyOnOff === 'SKIP') {
|
||||
callOnWrite = function () {
|
||||
self.reply = replyOnOff;
|
||||
};
|
||||
}
|
||||
}
|
||||
return this.internal_send_command(new Command('client', arr, callback, call_on_write));
|
||||
return this.internalSendCommand(new Command('client', arr, callback, callOnWrite));
|
||||
};
|
||||
|
||||
Multi.prototype.client = Multi.prototype.CLIENT = function client () {
|
||||
@@ -298,18 +298,18 @@ Multi.prototype.client = Multi.prototype.CLIENT = function client () {
|
||||
}
|
||||
}
|
||||
var self = this._client;
|
||||
var call_on_write = undefined;
|
||||
var callOnWrite = undefined;
|
||||
// CLIENT REPLY ON|OFF|SKIP
|
||||
/* istanbul ignore next: TODO: Remove this as soon as Travis runs Redis 3.2 */
|
||||
if (arr.length === 2 && arr[0].toString().toUpperCase() === 'REPLY') {
|
||||
var reply_on_off = arr[1].toString().toUpperCase();
|
||||
if (reply_on_off === 'ON' || reply_on_off === 'OFF' || reply_on_off === 'SKIP') {
|
||||
call_on_write = function () {
|
||||
self.reply = reply_on_off;
|
||||
var replyOnOff = arr[1].toString().toUpperCase();
|
||||
if (replyOnOff === 'ON' || replyOnOff === 'OFF' || replyOnOff === 'SKIP') {
|
||||
callOnWrite = function () {
|
||||
self.reply = replyOnOff;
|
||||
};
|
||||
}
|
||||
}
|
||||
this.queue.push(new Command('client', arr, callback, call_on_write));
|
||||
this.queue.push(new Command('client', arr, callback, callOnWrite));
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -349,7 +349,7 @@ RedisClient.prototype.hmset = RedisClient.prototype.HMSET = function hmset () {
|
||||
arr[i] = arguments[i];
|
||||
}
|
||||
}
|
||||
return this.internal_send_command(new Command('hmset', arr, callback));
|
||||
return this.internalSendCommand(new Command('hmset', arr, callback));
|
||||
};
|
||||
|
||||
Multi.prototype.hmset = Multi.prototype.HMSET = function hmset () {
|
||||
@@ -413,10 +413,10 @@ RedisClient.prototype.subscribe = RedisClient.prototype.SUBSCRIBE = function sub
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
var callOnWrite = function () {
|
||||
self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
|
||||
};
|
||||
return this.internal_send_command(new Command('subscribe', arr, callback, call_on_write));
|
||||
return this.internalSendCommand(new Command('subscribe', arr, callback, callOnWrite));
|
||||
};
|
||||
|
||||
Multi.prototype.subscribe = Multi.prototype.SUBSCRIBE = function subscribe () {
|
||||
@@ -440,10 +440,10 @@ Multi.prototype.subscribe = Multi.prototype.SUBSCRIBE = function subscribe () {
|
||||
}
|
||||
}
|
||||
var self = this._client;
|
||||
var call_on_write = function () {
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
var callOnWrite = function () {
|
||||
self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
|
||||
};
|
||||
this.queue.push(new Command('subscribe', arr, callback, call_on_write));
|
||||
this.queue.push(new Command('subscribe', arr, callback, callOnWrite));
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -468,11 +468,11 @@ RedisClient.prototype.unsubscribe = RedisClient.prototype.UNSUBSCRIBE = function
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
var callOnWrite = function () {
|
||||
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
|
||||
};
|
||||
return this.internal_send_command(new Command('unsubscribe', arr, callback, call_on_write));
|
||||
return this.internalSendCommand(new Command('unsubscribe', arr, callback, callOnWrite));
|
||||
};
|
||||
|
||||
Multi.prototype.unsubscribe = Multi.prototype.UNSUBSCRIBE = function unsubscribe () {
|
||||
@@ -496,11 +496,11 @@ Multi.prototype.unsubscribe = Multi.prototype.UNSUBSCRIBE = function unsubscribe
|
||||
}
|
||||
}
|
||||
var self = this._client;
|
||||
var call_on_write = function () {
|
||||
var callOnWrite = function () {
|
||||
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
|
||||
};
|
||||
this.queue.push(new Command('unsubscribe', arr, callback, call_on_write));
|
||||
this.queue.push(new Command('unsubscribe', arr, callback, callOnWrite));
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -525,10 +525,10 @@ RedisClient.prototype.psubscribe = RedisClient.prototype.PSUBSCRIBE = function p
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
var callOnWrite = function () {
|
||||
self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
|
||||
};
|
||||
return this.internal_send_command(new Command('psubscribe', arr, callback, call_on_write));
|
||||
return this.internalSendCommand(new Command('psubscribe', arr, callback, callOnWrite));
|
||||
};
|
||||
|
||||
Multi.prototype.psubscribe = Multi.prototype.PSUBSCRIBE = function psubscribe () {
|
||||
@@ -552,10 +552,10 @@ Multi.prototype.psubscribe = Multi.prototype.PSUBSCRIBE = function psubscribe ()
|
||||
}
|
||||
}
|
||||
var self = this._client;
|
||||
var call_on_write = function () {
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
var callOnWrite = function () {
|
||||
self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
|
||||
};
|
||||
this.queue.push(new Command('psubscribe', arr, callback, call_on_write));
|
||||
this.queue.push(new Command('psubscribe', arr, callback, callOnWrite));
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -580,11 +580,11 @@ RedisClient.prototype.punsubscribe = RedisClient.prototype.PUNSUBSCRIBE = functi
|
||||
}
|
||||
}
|
||||
var self = this;
|
||||
var call_on_write = function () {
|
||||
var callOnWrite = function () {
|
||||
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
|
||||
};
|
||||
return this.internal_send_command(new Command('punsubscribe', arr, callback, call_on_write));
|
||||
return this.internalSendCommand(new Command('punsubscribe', arr, callback, callOnWrite));
|
||||
};
|
||||
|
||||
Multi.prototype.punsubscribe = Multi.prototype.PUNSUBSCRIBE = function punsubscribe () {
|
||||
@@ -608,10 +608,10 @@ Multi.prototype.punsubscribe = Multi.prototype.PUNSUBSCRIBE = function punsubscr
|
||||
}
|
||||
}
|
||||
var self = this._client;
|
||||
var call_on_write = function () {
|
||||
var callOnWrite = function () {
|
||||
// Pub sub has to be activated even if not in pub sub mode, as the return value is manipulated in the callback
|
||||
self.pub_sub_mode = self.pub_sub_mode || self.command_queue.length + 1;
|
||||
self.pubSubMode = self.pubSubMode || self.commandQueue.length + 1;
|
||||
};
|
||||
this.queue.push(new Command('punsubscribe', arr, callback, call_on_write));
|
||||
this.queue.push(new Command('punsubscribe', arr, callback, callOnWrite));
|
||||
return this;
|
||||
};
|
||||
|
102
lib/multi.js
102
lib/multi.js
@@ -7,25 +7,25 @@ var Command = require('./command');
|
||||
function Multi (client, args) {
|
||||
this._client = client;
|
||||
this.queue = new Queue();
|
||||
var command, tmp_args;
|
||||
var command, tmpArgs;
|
||||
if (args) { // Either undefined or an array. Fail hard if it's not an array
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
command = args[i][0];
|
||||
tmp_args = args[i].slice(1);
|
||||
tmpArgs = args[i].slice(1);
|
||||
if (Array.isArray(command)) {
|
||||
this[command[0]].apply(this, command.slice(1).concat(tmp_args));
|
||||
this[command[0]].apply(this, command.slice(1).concat(tmpArgs));
|
||||
} else {
|
||||
this[command].apply(this, tmp_args);
|
||||
this[command].apply(this, tmpArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pipeline_transaction_command (self, command_obj, index) {
|
||||
function pipelineTransactionCommand (self, commandObj, index) {
|
||||
// Queueing is done first, then the commands are executed
|
||||
var tmp = command_obj.callback;
|
||||
command_obj.callback = function (err, reply) {
|
||||
// Ignore the multi command. This is applied by node_redis and the user does not benefit by it
|
||||
var tmp = commandObj.callback;
|
||||
commandObj.callback = function (err, reply) {
|
||||
// Ignore the multi command. This is applied by nodeRedis and the user does not benefit by it
|
||||
if (err && index !== -1) {
|
||||
if (tmp) {
|
||||
tmp(err);
|
||||
@@ -34,22 +34,22 @@ function pipeline_transaction_command (self, command_obj, index) {
|
||||
self.errors.push(err);
|
||||
}
|
||||
// Keep track of who wants buffer responses:
|
||||
// By the time the callback is called the command_obj got the buffer_args attribute attached
|
||||
self.wants_buffers[index] = command_obj.buffer_args;
|
||||
command_obj.callback = tmp;
|
||||
// By the time the callback is called the commandObj got the bufferArgs attribute attached
|
||||
self.wantsBuffers[index] = commandObj.bufferArgs;
|
||||
commandObj.callback = tmp;
|
||||
};
|
||||
self._client.internal_send_command(command_obj);
|
||||
self._client.internalSendCommand(commandObj);
|
||||
}
|
||||
|
||||
Multi.prototype.exec_atomic = Multi.prototype.EXEC_ATOMIC = Multi.prototype.execAtomic = function exec_atomic (callback) {
|
||||
Multi.prototype.execAtomic = Multi.prototype.EXEC_ATOMIC = Multi.prototype.execAtomic = function execAtomic (callback) {
|
||||
if (this.queue.length < 2) {
|
||||
return this.exec_batch(callback);
|
||||
return this.execBatch(callback);
|
||||
}
|
||||
return this.exec(callback);
|
||||
};
|
||||
|
||||
function multi_callback (self, err, replies) {
|
||||
var i = 0, command_obj;
|
||||
function multiCallback (self, err, replies) {
|
||||
var i = 0, commandObj;
|
||||
|
||||
if (err) {
|
||||
err.errors = self.errors;
|
||||
@@ -63,22 +63,22 @@ function multi_callback (self, err, replies) {
|
||||
}
|
||||
|
||||
if (replies) {
|
||||
while (command_obj = self.queue.shift()) {
|
||||
while (commandObj = self.queue.shift()) {
|
||||
if (replies[i] instanceof Error) {
|
||||
var match = replies[i].message.match(utils.err_code);
|
||||
var match = replies[i].message.match(utils.errCode);
|
||||
// LUA script could return user errors that don't behave like all other errors!
|
||||
if (match) {
|
||||
replies[i].code = match[1];
|
||||
}
|
||||
replies[i].command = command_obj.command.toUpperCase();
|
||||
if (typeof command_obj.callback === 'function') {
|
||||
command_obj.callback(replies[i]);
|
||||
replies[i].command = commandObj.command.toUpperCase();
|
||||
if (typeof commandObj.callback === 'function') {
|
||||
commandObj.callback(replies[i]);
|
||||
}
|
||||
} else {
|
||||
// If we asked for strings, even in detect_buffers mode, then return strings:
|
||||
replies[i] = self._client.handle_reply(replies[i], command_obj.command, self.wants_buffers[i]);
|
||||
if (typeof command_obj.callback === 'function') {
|
||||
command_obj.callback(null, replies[i]);
|
||||
// If we asked for strings, even in detectBuffers mode, then return strings:
|
||||
replies[i] = self._client.handleReply(replies[i], commandObj.command, self.wantsBuffers[i]);
|
||||
if (typeof commandObj.callback === 'function') {
|
||||
commandObj.callback(null, replies[i]);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
@@ -90,37 +90,37 @@ function multi_callback (self, err, replies) {
|
||||
}
|
||||
}
|
||||
|
||||
Multi.prototype.exec_transaction = function exec_transaction (callback) {
|
||||
Multi.prototype.execTransaction = function execTransaction (callback) {
|
||||
if (this.monitoring || this._client.monitoring) {
|
||||
var err = new RangeError(
|
||||
'Using transaction with a client that is in monitor mode does not work due to faulty return values of Redis.'
|
||||
);
|
||||
err.command = 'EXEC';
|
||||
err.code = 'EXECABORT';
|
||||
return utils.reply_in_order(this._client, callback, err);
|
||||
return utils.replyInOrder(this._client, callback, err);
|
||||
}
|
||||
var self = this;
|
||||
var len = self.queue.length;
|
||||
self.errors = [];
|
||||
self.callback = callback;
|
||||
self._client.cork();
|
||||
self.wants_buffers = new Array(len);
|
||||
pipeline_transaction_command(self, new Command('multi', []), -1);
|
||||
self.wantsBuffers = new Array(len);
|
||||
pipelineTransactionCommand(self, new Command('multi', []), -1);
|
||||
// Drain queue, callback will catch 'QUEUED' or error
|
||||
for (var index = 0; index < len; index++) {
|
||||
// The commands may not be shifted off, since they are needed in the result handler
|
||||
pipeline_transaction_command(self, self.queue.get(index), index);
|
||||
pipelineTransactionCommand(self, self.queue.get(index), index);
|
||||
}
|
||||
|
||||
self._client.internal_send_command(new Command('exec', [], function (err, replies) {
|
||||
multi_callback(self, err, replies);
|
||||
self._client.internalSendCommand(new Command('exec', [], function (err, replies) {
|
||||
multiCallback(self, err, replies);
|
||||
}));
|
||||
self._client.uncork();
|
||||
return !self._client.should_buffer;
|
||||
return !self._client.shouldBuffer;
|
||||
};
|
||||
|
||||
function batch_callback (self, cb, i) {
|
||||
return function batch_callback (err, res) {
|
||||
function batchCallback (self, cb, i) {
|
||||
return function batchCallback (err, res) {
|
||||
if (err) {
|
||||
self.results[i] = err;
|
||||
// Add the position to the error
|
||||
@@ -132,24 +132,24 @@ function batch_callback (self, cb, i) {
|
||||
};
|
||||
}
|
||||
|
||||
Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = function exec_batch (callback) {
|
||||
Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.execBatch = function execBatch (callback) {
|
||||
var self = this;
|
||||
var len = self.queue.length;
|
||||
var index = 0;
|
||||
var command_obj;
|
||||
var commandObj;
|
||||
if (len === 0) {
|
||||
utils.reply_in_order(self._client, callback, null, []);
|
||||
return !self._client.should_buffer;
|
||||
utils.replyInOrder(self._client, callback, null, []);
|
||||
return !self._client.shouldBuffer;
|
||||
}
|
||||
self._client.cork();
|
||||
if (!callback) {
|
||||
while (command_obj = self.queue.shift()) {
|
||||
self._client.internal_send_command(command_obj);
|
||||
while (commandObj = self.queue.shift()) {
|
||||
self._client.internalSendCommand(commandObj);
|
||||
}
|
||||
self._client.uncork();
|
||||
return !self._client.should_buffer;
|
||||
return !self._client.shouldBuffer;
|
||||
}
|
||||
var callback_without_own_cb = function (err, res) {
|
||||
var callbackWithoutOwnCb = function (err, res) {
|
||||
if (err) {
|
||||
self.results.push(err);
|
||||
// Add the position to the error
|
||||
@@ -161,27 +161,27 @@ Multi.prototype.exec = Multi.prototype.EXEC = Multi.prototype.exec_batch = funct
|
||||
// Do not emit an error here. Otherwise each error would result in one emit.
|
||||
// The errors will be returned in the result anyway
|
||||
};
|
||||
var last_callback = function (cb) {
|
||||
var lastCallback = function (cb) {
|
||||
return function (err, res) {
|
||||
cb(err, res);
|
||||
callback(null, self.results);
|
||||
};
|
||||
};
|
||||
self.results = [];
|
||||
while (command_obj = self.queue.shift()) {
|
||||
if (typeof command_obj.callback === 'function') {
|
||||
command_obj.callback = batch_callback(self, command_obj.callback, index);
|
||||
while (commandObj = self.queue.shift()) {
|
||||
if (typeof commandObj.callback === 'function') {
|
||||
commandObj.callback = batchCallback(self, commandObj.callback, index);
|
||||
} else {
|
||||
command_obj.callback = callback_without_own_cb;
|
||||
commandObj.callback = callbackWithoutOwnCb;
|
||||
}
|
||||
if (typeof callback === 'function' && index === len - 1) {
|
||||
command_obj.callback = last_callback(command_obj.callback);
|
||||
commandObj.callback = lastCallback(commandObj.callback);
|
||||
}
|
||||
this._client.internal_send_command(command_obj);
|
||||
this._client.internalSendCommand(commandObj);
|
||||
index++;
|
||||
}
|
||||
self._client.uncork();
|
||||
return !self._client.should_buffer;
|
||||
return !self._client.shouldBuffer;
|
||||
};
|
||||
|
||||
module.exports = Multi;
|
||||
|
45
lib/utils.js
45
lib/utils.js
@@ -30,10 +30,8 @@ function replyToStrings (reply) {
|
||||
return reply;
|
||||
}
|
||||
|
||||
var camelCase;
|
||||
// Deep clone arbitrary objects with arrays. Can't handle cyclic structures (results in a range error)
|
||||
// Any attribute with a non primitive value besides object and array will be passed by reference (e.g. Buffers, Maps, Functions)
|
||||
// All capital letters are going to be replaced with a lower case letter and a underscore infront of it
|
||||
function clone (obj) {
|
||||
var copy;
|
||||
if (Array.isArray(obj)) {
|
||||
@@ -48,18 +46,7 @@ function clone (obj) {
|
||||
var elems = Object.keys(obj);
|
||||
var elem;
|
||||
while (elem = elems.pop()) {
|
||||
if (elem === 'tls') { // special handle tls
|
||||
copy[elem] = obj[elem];
|
||||
continue;
|
||||
}
|
||||
// Accept camelCase options and convert them to snake_case
|
||||
var snake_case = elem.replace(/[A-Z][^A-Z]/g, '_$&').toLowerCase();
|
||||
// If camelCase is detected, pass it to the client, so all variables are going to be camelCased
|
||||
// There are no deep nested options objects yet, but let's handle this future proof
|
||||
if (snake_case !== elem.toLowerCase()) {
|
||||
camelCase = true;
|
||||
}
|
||||
copy[snake_case] = clone(obj[elem]);
|
||||
copy[elem] = clone(obj[elem]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
@@ -67,12 +54,7 @@ function clone (obj) {
|
||||
}
|
||||
|
||||
function convenienceClone (obj) {
|
||||
camelCase = false;
|
||||
obj = clone(obj) || {};
|
||||
if (camelCase) {
|
||||
obj.camel_case = true;
|
||||
}
|
||||
return obj;
|
||||
return clone(obj) || {};
|
||||
}
|
||||
|
||||
function callbackOrEmit (self, callback, err, res) {
|
||||
@@ -86,20 +68,19 @@ function callbackOrEmit (self, callback, err, res) {
|
||||
function replyInOrder (self, callback, err, res, queue) {
|
||||
// If the queue is explicitly passed, use that, otherwise fall back to the offline queue first,
|
||||
// as there might be commands in both queues at the same time
|
||||
var command_obj;
|
||||
/* istanbul ignore if: TODO: Remove this as soon as we test Redis 3.2 on travis */
|
||||
var commandObj;
|
||||
if (queue) {
|
||||
command_obj = queue.peekBack();
|
||||
commandObj = queue.peekBack();
|
||||
} else {
|
||||
command_obj = self.offline_queue.peekBack() || self.command_queue.peekBack();
|
||||
commandObj = self.offlineQueue.peekBack() || self.commandQueue.peekBack();
|
||||
}
|
||||
if (!command_obj) {
|
||||
if (!commandObj) {
|
||||
process.nextTick(function () {
|
||||
callbackOrEmit(self, callback, err, res);
|
||||
});
|
||||
} else {
|
||||
var tmp = command_obj.callback;
|
||||
command_obj.callback = tmp ?
|
||||
var tmp = commandObj.callback;
|
||||
commandObj.callback = tmp ?
|
||||
function (e, r) {
|
||||
tmp(e, r);
|
||||
callbackOrEmit(self, callback, err, res);
|
||||
@@ -114,11 +95,11 @@ function replyInOrder (self, callback, err, res, queue) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
reply_to_strings: replyToStrings,
|
||||
reply_to_object: replyToObject,
|
||||
err_code: /^([A-Z]+)\s+(.+)$/,
|
||||
replyToStrings: replyToStrings,
|
||||
replyToObject: replyToObject,
|
||||
errCode: /^([A-Z]+)\s+(.+)$/,
|
||||
monitor_regex: /^[0-9]{10,11}\.[0-9]+ \[[0-9]+ .+\]( ".+?")+$/,
|
||||
clone: convenienceClone,
|
||||
callback_or_emit: callbackOrEmit,
|
||||
reply_in_order: replyInOrder
|
||||
callbackOrEmit: callbackOrEmit,
|
||||
replyInOrder: replyInOrder
|
||||
};
|
||||
|
@@ -58,8 +58,8 @@ describe('client authentication', function () {
|
||||
assert(now - time < 225, 'Time should be below 255 ms (the reconnect should only take a bit above 100 ms) and is ' + (now - time));
|
||||
done();
|
||||
});
|
||||
var tmp = client.command_queue.get(0).callback;
|
||||
client.command_queue.get(0).callback = function (err, res) {
|
||||
var tmp = client.commandQueue.get(0).callback;
|
||||
client.commandQueue.get(0).callback = function (err, res) {
|
||||
client.auth = function (pass, callback) {
|
||||
callback(null, 'retry worked');
|
||||
};
|
||||
@@ -115,15 +115,15 @@ describe('client authentication', function () {
|
||||
client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT + '?db=2&password=' + auth);
|
||||
assert.strictEqual(client.options.db, '2');
|
||||
assert.strictEqual(client.options.password, auth);
|
||||
assert.strictEqual(client.auth_pass, auth);
|
||||
assert.strictEqual(client.authPass, auth);
|
||||
client.on('ready', function () {
|
||||
// Set a key so the used database is returned in the info command
|
||||
client.set('foo', 'bar');
|
||||
client.get('foo');
|
||||
assert.strictEqual(client.server_info.db2, undefined);
|
||||
// Using the info command should update the server_info
|
||||
assert.strictEqual(client.serverInfo.db2, undefined);
|
||||
// Using the info command should update the serverInfo
|
||||
client.info(function (err, res) {
|
||||
assert(typeof client.server_info.db2 === 'object');
|
||||
assert(typeof client.serverInfo.db2 === 'object');
|
||||
});
|
||||
client.flushdb(done);
|
||||
});
|
||||
@@ -134,18 +134,18 @@ describe('client authentication', function () {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
auth_pass: auth
|
||||
authPass: auth
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.on('ready', done);
|
||||
});
|
||||
|
||||
it('allows auth and no_ready_check to be provided as config option for client', function (done) {
|
||||
it('allows auth and noReadyCheck to be provided as config option for client', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
password: auth,
|
||||
no_ready_check: true
|
||||
noReadyCheck: true
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.on('ready', done);
|
||||
@@ -166,9 +166,9 @@ describe('client authentication', function () {
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.auth(auth);
|
||||
client.on('ready', function () {
|
||||
if (this.times_connected < 3) {
|
||||
if (this.timesConnected < 3) {
|
||||
var interval = setInterval(function () {
|
||||
if (client.commandQueueLength !== 0) {
|
||||
if (client.commandQueue.length !== 0) {
|
||||
return;
|
||||
}
|
||||
clearInterval(interval);
|
||||
@@ -176,7 +176,7 @@ describe('client authentication', function () {
|
||||
client.stream.destroy();
|
||||
client.set('foo', 'bar');
|
||||
client.get('foo'); // Errors would bubble
|
||||
assert.strictEqual(client.offlineQueueLength, 2);
|
||||
assert.strictEqual(client.offlineQueue.length, 2);
|
||||
}, 1);
|
||||
} else {
|
||||
done();
|
||||
@@ -218,7 +218,7 @@ describe('client authentication', function () {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
auth_pass: auth
|
||||
authPass: auth
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.on('ready', function () {
|
||||
@@ -226,11 +226,11 @@ describe('client authentication', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('does not allow any commands to be processed if not authenticated using no_ready_check true', function (done) {
|
||||
it('does not allow any commands to be processed if not authenticated using noReadyCheck true', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
no_ready_check: true
|
||||
noReadyCheck: true
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
client.on('ready', function () {
|
||||
@@ -257,7 +257,7 @@ describe('client authentication', function () {
|
||||
it('should emit an error if the provided password is faulty', function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) this.skip();
|
||||
client = redis.createClient({
|
||||
password: 'wrong_password'
|
||||
password: 'wrongPassword'
|
||||
});
|
||||
client.once('error', function (err) {
|
||||
assert.strictEqual(err.message, 'ERR invalid password');
|
||||
@@ -275,7 +275,7 @@ describe('client authentication', function () {
|
||||
client.set('foo', 'bar');
|
||||
client.subscribe('somechannel', 'another channel', function (err, res) {
|
||||
client.once('ready', function () {
|
||||
assert.strictEqual(client.pub_sub_mode, 1);
|
||||
assert.strictEqual(client.pubSubMode, 1);
|
||||
client.get('foo', function (err, res) {
|
||||
assert(/ERR only \(P\)SUBSCRIBE \/ \(P\)UNSUBSCRIBE/.test(err.message));
|
||||
done();
|
||||
@@ -284,7 +284,7 @@ describe('client authentication', function () {
|
||||
});
|
||||
client.once('ready', function () {
|
||||
// Coherent behavior with all other offline commands fires commands before emitting but does not wait till they return
|
||||
assert.strictEqual(client.pub_sub_mode, 2);
|
||||
assert.strictEqual(client.pubSubMode, 2);
|
||||
client.ping(function () { // Make sure all commands were properly processed already
|
||||
client.stream.destroy();
|
||||
});
|
||||
@@ -302,7 +302,7 @@ describe('client authentication', function () {
|
||||
noReadyCheck: true
|
||||
});
|
||||
client = redis.createClient.apply(null, args);
|
||||
assert.strictEqual(client.selected_db, undefined);
|
||||
assert.strictEqual(client.selectedDb, undefined);
|
||||
var end = helper.callFuncAfter(done, 8);
|
||||
client.on('monitor', function () {
|
||||
end(); // Should be called for each command after monitor
|
||||
@@ -310,9 +310,9 @@ describe('client authentication', function () {
|
||||
client.batch()
|
||||
.auth(auth)
|
||||
.SELECT(5, function (err, res) {
|
||||
assert.strictEqual(client.selected_db, 5);
|
||||
assert.strictEqual(client.selectedDb, 5);
|
||||
assert.strictEqual(res, 'OK');
|
||||
assert.notDeepEqual(client.serverInfo.db5, { avg_ttl: 0, expires: 0, keys: 1 });
|
||||
assert.notDeepEqual(client.serverInfo.db5, { avgTtl: 0, expires: 0, keys: 1 });
|
||||
})
|
||||
.monitor()
|
||||
.set('foo', 'bar', helper.isString('OK'))
|
||||
|
@@ -23,7 +23,7 @@ describe("The 'blpop' method", function () {
|
||||
|
||||
it('pops value immediately if list contains values', function (done) {
|
||||
bclient = redis.createClient.apply(null, args);
|
||||
redis.debug_mode = true;
|
||||
redis.debugMode = true;
|
||||
var text = '';
|
||||
var unhookIntercept = intercept(function (data) {
|
||||
text += data;
|
||||
@@ -32,7 +32,7 @@ describe("The 'blpop' method", function () {
|
||||
client.rpush('blocking list', 'initial value', helper.isNumber(1));
|
||||
unhookIntercept();
|
||||
assert(/^Send 127\.0\.0\.1:6379 id [0-9]+: \*3\r\n\$5\r\nrpush\r\n\$13\r\nblocking list\r\n\$13\r\ninitial value\r\n\n$/.test(text));
|
||||
redis.debug_mode = false;
|
||||
redis.debugMode = false;
|
||||
bclient.blpop('blocking list', 0, function (err, value) {
|
||||
assert.strictEqual(value[0], 'blocking list');
|
||||
assert.strictEqual(value[1], 'initial value');
|
||||
|
@@ -33,8 +33,8 @@ describe("The 'hgetall' method", function () {
|
||||
});
|
||||
|
||||
it('handles fetching keys set using an object', function (done) {
|
||||
client.batch().HMSET('msg_test', { message: 'hello' }, undefined).exec();
|
||||
client.hgetall('msg_test', function (err, obj) {
|
||||
client.batch().HMSET('msgTest', { message: 'hello' }, undefined).exec();
|
||||
client.hgetall('msgTest', function (err, obj) {
|
||||
assert.strictEqual(1, Object.keys(obj).length);
|
||||
assert.strictEqual(obj.message, 'hello');
|
||||
done(err);
|
||||
@@ -52,7 +52,7 @@ describe("The 'hgetall' method", function () {
|
||||
describe('binary client', function () {
|
||||
var client;
|
||||
var args = config.configureClient(ip, {
|
||||
return_buffers: true
|
||||
returnBuffers: true
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
|
@@ -52,7 +52,7 @@ describe("The 'incr' method", function () {
|
||||
});
|
||||
|
||||
it('count above the safe integers as strings', function (done) {
|
||||
args[2].string_numbers = true;
|
||||
args[2].stringNumbers = true;
|
||||
client = redis.createClient.apply(null, args);
|
||||
// Set a value to the maximum safe allowed javascript number (2^53)
|
||||
client.set(key, MAX_SAFE_INTEGER, helper.isNotError());
|
||||
|
@@ -41,24 +41,24 @@ describe("The 'info' method", function () {
|
||||
client.set('foo', 'bar');
|
||||
client.info('keyspace');
|
||||
client.select(2, function () {
|
||||
assert.strictEqual(Object.keys(client.server_info).length, 2, 'Key length should be three');
|
||||
assert.strictEqual(typeof client.server_info.db0, 'object', 'db0 keyspace should be an object');
|
||||
assert.strictEqual(Object.keys(client.serverInfo).length, 2, 'Key length should be three');
|
||||
assert.strictEqual(typeof client.serverInfo.db0, 'object', 'db0 keyspace should be an object');
|
||||
});
|
||||
client.info(['keyspace']);
|
||||
client.set('foo', 'bar');
|
||||
client.info('all', function (err, res) {
|
||||
assert(Object.keys(client.server_info).length > 3, 'Key length should be way above three');
|
||||
assert.strictEqual(typeof client.server_info.redis_version, 'string');
|
||||
assert.strictEqual(typeof client.server_info.db2, 'object');
|
||||
assert(Object.keys(client.serverInfo).length > 3, 'Key length should be way above three');
|
||||
assert.strictEqual(typeof client.serverInfo.redis_version, 'string');
|
||||
assert.strictEqual(typeof client.serverInfo.db2, 'object');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('check redis v.2.4 support', function (done) {
|
||||
var end = helper.callFuncAfter(done, 2);
|
||||
client.internal_send_command = function (command_obj) {
|
||||
assert.strictEqual(command_obj.args.length, 0);
|
||||
assert.strictEqual(command_obj.command, 'info');
|
||||
client.internalSendCommand = function (commandObj) {
|
||||
assert.strictEqual(commandObj.args.length, 0);
|
||||
assert.strictEqual(commandObj.command, 'info');
|
||||
end();
|
||||
};
|
||||
client.info();
|
||||
|
@@ -31,22 +31,22 @@ describe("The 'keys' method", function () {
|
||||
});
|
||||
|
||||
it('handles a large packet size', function (done) {
|
||||
var keys_values = [];
|
||||
var keysValues = [];
|
||||
|
||||
for (var i = 0; i < 200; i++) {
|
||||
var key_value = [
|
||||
var keyValue = [
|
||||
'multibulk:' + crypto.randomBytes(256).toString('hex'), // use long strings as keys to ensure generation of large packet
|
||||
'test val ' + i
|
||||
];
|
||||
keys_values.push(key_value);
|
||||
keysValues.push(keyValue);
|
||||
}
|
||||
|
||||
client.mset(keys_values.reduce(function (a, b) {
|
||||
client.mset(keysValues.reduce(function (a, b) {
|
||||
return a.concat(b);
|
||||
}), helper.isString('OK'));
|
||||
|
||||
client.keys('multibulk:*', function (err, results) {
|
||||
assert.deepEqual(keys_values.map(function (val) {
|
||||
assert.deepEqual(keysValues.map(function (val) {
|
||||
return val[0];
|
||||
}).sort(), results.sort());
|
||||
return done(err);
|
||||
|
@@ -46,10 +46,10 @@ describe("The 'select' method", function () {
|
||||
|
||||
it('changes the database and calls the callback', function (done) {
|
||||
// default value of null means database 0 will be used.
|
||||
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined');
|
||||
assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
|
||||
var buffering = client.SELECT(1, function (err, res) {
|
||||
helper.isNotError()(err, res);
|
||||
assert.strictEqual(client.selected_db, 1, 'db should be 1 after select');
|
||||
assert.strictEqual(client.selectedDb, 1, 'db should be 1 after select');
|
||||
done();
|
||||
});
|
||||
assert(typeof buffering === 'boolean');
|
||||
@@ -58,10 +58,10 @@ describe("The 'select' method", function () {
|
||||
describe('and a callback is specified', function () {
|
||||
describe('with a valid db index', function () {
|
||||
it('selects the appropriate database', function (done) {
|
||||
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined');
|
||||
assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
|
||||
client.select(1, function (err) {
|
||||
assert.equal(err, null);
|
||||
assert.equal(client.selected_db, 1, 'we should have selected the new valid DB');
|
||||
assert.equal(client.selectedDb, 1, 'we should have selected the new valid DB');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -69,7 +69,7 @@ describe("The 'select' method", function () {
|
||||
|
||||
describe('with an invalid db index', function () {
|
||||
it('returns an error', function (done) {
|
||||
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined');
|
||||
assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
|
||||
client.select(9999, function (err) {
|
||||
assert.equal(err.code, 'ERR');
|
||||
assert.equal(err.message, 'ERR invalid DB index');
|
||||
@@ -82,10 +82,10 @@ describe("The 'select' method", function () {
|
||||
describe('and no callback is specified', function () {
|
||||
describe('with a valid db index', function () {
|
||||
it('selects the appropriate database', function (done) {
|
||||
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined');
|
||||
assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
|
||||
client.select(1);
|
||||
setTimeout(function () {
|
||||
assert.equal(client.selected_db, 1, 'we should have selected the new valid DB');
|
||||
assert.equal(client.selectedDb, 1, 'we should have selected the new valid DB');
|
||||
done();
|
||||
}, 25);
|
||||
});
|
||||
@@ -93,7 +93,7 @@ describe("The 'select' method", function () {
|
||||
|
||||
describe('with an invalid db index', function () {
|
||||
it('emits an error when callback not provided', function (done) {
|
||||
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined');
|
||||
assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
|
||||
|
||||
client.on('error', function (err) {
|
||||
assert.strictEqual(err.command, 'SELECT');
|
||||
@@ -108,14 +108,14 @@ describe("The 'select' method", function () {
|
||||
|
||||
describe('reconnection occurs', function () {
|
||||
it('selects the appropriate database after a reconnect', function (done) {
|
||||
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined');
|
||||
assert.strictEqual(client.selectedDb, undefined, 'default db should be undefined');
|
||||
client.select(3);
|
||||
client.set('foo', 'bar', function () {
|
||||
client.stream.destroy();
|
||||
});
|
||||
client.once('ready', function () {
|
||||
assert.strictEqual(client.selected_db, 3);
|
||||
assert(typeof client.server_info.db3 === 'object');
|
||||
assert.strictEqual(client.selectedDb, 3);
|
||||
assert(typeof client.serverInfo.db3 === 'object');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@@ -39,9 +39,9 @@ describe("The 'srem' method", function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('allows multiple values to be removed with send_command', function (done) {
|
||||
client.send_command('sadd', ['set0', 'member0', 'member1', 'member2'], helper.isNumber(3));
|
||||
client.send_command('srem', ['set0', 'member1', 'member2'], helper.isNumber(2));
|
||||
it('allows multiple values to be removed with sendCommand', function (done) {
|
||||
client.sendCommand('sadd', ['set0', 'member0', 'member1', 'member2'], helper.isNumber(3));
|
||||
client.sendCommand('srem', ['set0', 'member1', 'member2'], helper.isNumber(2));
|
||||
client.smembers('set0', function (err, res) {
|
||||
assert.strictEqual(res.length, 1);
|
||||
assert.ok(~res.indexOf('member0'));
|
||||
|
@@ -28,7 +28,7 @@ describe("The 'zscan' method", function () {
|
||||
for (var i = 0; i < 500; i++) {
|
||||
hash['key_' + i] = 'value_' + i;
|
||||
set.push('member_' + i);
|
||||
zset.push(i, 'z_member_' + i);
|
||||
zset.push(i, 'zMember_' + i);
|
||||
}
|
||||
client.hmset('hash:1', hash);
|
||||
client.sadd('set:1', set);
|
||||
|
@@ -45,7 +45,7 @@ describe('master slave sync', function () {
|
||||
var firstInfo;
|
||||
slave = redis.createClient({
|
||||
port: port,
|
||||
retry_strategy: function (options) {
|
||||
retryStrategy: function (options) {
|
||||
// Try to reconnect in very small intervals to catch the master_link_status down before the sync completes
|
||||
return 10;
|
||||
}
|
||||
@@ -57,7 +57,7 @@ describe('master slave sync', function () {
|
||||
i++;
|
||||
tmp(err, res);
|
||||
if (!firstInfo || Object.keys(firstInfo).length === 0) {
|
||||
firstInfo = slave.server_info;
|
||||
firstInfo = slave.serverInfo;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -68,7 +68,7 @@ describe('master slave sync', function () {
|
||||
var end = helper.callFuncAfter(done, 2);
|
||||
|
||||
slave.on('ready', function () {
|
||||
assert.strictEqual(this.server_info.master_link_status, 'up');
|
||||
assert.strictEqual(this.serverInfo.master_link_status, 'up');
|
||||
assert.strictEqual(firstInfo.master_link_status, 'down');
|
||||
assert(i > 1);
|
||||
this.get('foo300', function (err, res) {
|
||||
|
@@ -29,7 +29,7 @@ describe('connection tests', function () {
|
||||
assert.strictEqual(client.stream.listeners('error').length, 1);
|
||||
assert.strictEqual(client.address, '"Private stream"');
|
||||
// Pretent a reconnect event
|
||||
client.create_stream();
|
||||
client.createStream();
|
||||
assert.strictEqual(client.stream, socket);
|
||||
assert.strictEqual(client.stream.listeners('error').length, 1);
|
||||
});
|
||||
@@ -40,7 +40,7 @@ describe('connection tests', function () {
|
||||
var called = 0;
|
||||
client = redis.createClient({
|
||||
port: 9999,
|
||||
retry_strategy: function (options) {
|
||||
retryStrategy: function (options) {
|
||||
var bool = client.quit(function (err, res) {
|
||||
assert.strictEqual(res, 'OK');
|
||||
assert.strictEqual(err, null);
|
||||
@@ -77,7 +77,7 @@ describe('connection tests', function () {
|
||||
it('calling quit while the connection is down without offline queue should end the connection right away', function (done) {
|
||||
var called = false;
|
||||
client = redis.createClient(9999, {
|
||||
enable_offline_queue: false
|
||||
enableOfflineQueue: false
|
||||
});
|
||||
client.set('foo', 'bar', function (err, res) {
|
||||
assert.strictEqual(err.message, 'SET can\'t be processed. The connection is not yet established and the offline queue is deactivated.');
|
||||
@@ -96,7 +96,7 @@ describe('connection tests', function () {
|
||||
it('calling quit while connected without offline queue should end the connection when all commands have finished', function (done) {
|
||||
var called = false;
|
||||
client = redis.createClient({
|
||||
enable_offline_queue: false
|
||||
enableOfflineQueue: false
|
||||
});
|
||||
client.on('ready', function () {
|
||||
client.set('foo', 'bar', function (err, res) {
|
||||
@@ -154,9 +154,9 @@ describe('connection tests', function () {
|
||||
describe('on lost connection', function () {
|
||||
|
||||
it('end connection while retry is still ongoing', function (done) {
|
||||
var connect_timeout = 1000; // in ms
|
||||
var connectTimeout = 1000; // in ms
|
||||
client = redis.createClient({
|
||||
connect_timeout: connect_timeout
|
||||
connectTimeout: connectTimeout
|
||||
});
|
||||
|
||||
client.once('ready', function () {
|
||||
@@ -165,7 +165,7 @@ describe('connection tests', function () {
|
||||
|
||||
client.on('reconnecting', function (params) {
|
||||
client.end(true);
|
||||
assert.strictEqual(params.times_connected, 1);
|
||||
assert.strictEqual(params.timesConnected, 1);
|
||||
setTimeout(done, 5);
|
||||
});
|
||||
});
|
||||
@@ -178,7 +178,7 @@ describe('connection tests', function () {
|
||||
retryStrategy: function () {}
|
||||
};
|
||||
client = redis.createClient(options);
|
||||
assert.strictEqual(client.connection_options.family, ip === 'IPv6' ? 6 : 4);
|
||||
assert.strictEqual(client.connectionOptions.family, ip === 'IPv6' ? 6 : 4);
|
||||
assert.strictEqual(Object.keys(options).length, 4);
|
||||
var end = helper.callFuncAfter(done, 2);
|
||||
|
||||
@@ -220,10 +220,10 @@ describe('connection tests', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('retry_strategy used to reconnect', function (done) {
|
||||
it('retryStrategy used to reconnect', function (done) {
|
||||
client = redis.createClient({
|
||||
retry_strategy: function (options) {
|
||||
if (options.total_retry_time > 150) {
|
||||
retryStrategy: function (options) {
|
||||
if (options.totalRetryTime > 150) {
|
||||
client.set('foo', 'bar', function (err, res) {
|
||||
assert.strictEqual(err.message, 'Stream connection ended and command aborted.');
|
||||
assert.strictEqual(err.code, 'NR_CLOSED');
|
||||
@@ -265,18 +265,18 @@ describe('connection tests', function () {
|
||||
|
||||
describe('when not connected', function () {
|
||||
|
||||
it.skip('emit an error after the socket timeout exceeded the connect_timeout time', function (done) {
|
||||
var connect_timeout = 500; // in ms
|
||||
it.skip('emit an error after the socket timeout exceeded the connectTimeout time', function (done) {
|
||||
var connectTimeout = 500; // in ms
|
||||
client = redis.createClient({
|
||||
// Auto detect ipv4 and use non routable ip to trigger the timeout
|
||||
host: '10.255.255.1',
|
||||
connect_timeout: connect_timeout
|
||||
connectTimeout: connectTimeout
|
||||
});
|
||||
process.nextTick(function () {
|
||||
assert.strictEqual(client.stream.listeners('timeout').length, 1);
|
||||
});
|
||||
assert.strictEqual(client.address, '10.255.255.1:6379');
|
||||
assert.strictEqual(client.connection_options.family, 4);
|
||||
assert.strictEqual(client.connectionOptions.family, 4);
|
||||
|
||||
client.on('reconnecting', function (params) {
|
||||
throw new Error('No reconnect, since no connection was ever established');
|
||||
@@ -291,19 +291,19 @@ describe('connection tests', function () {
|
||||
// The code execution on windows is very slow at times
|
||||
var add = process.platform !== 'win32' ? 15 : 200;
|
||||
var now = Date.now();
|
||||
assert(now - time < connect_timeout + add, 'The real timeout time should be below ' + (connect_timeout + add) + 'ms but is: ' + (now - time));
|
||||
assert(now - time < connectTimeout + add, 'The real timeout time should be below ' + (connectTimeout + add) + 'ms but is: ' + (now - time));
|
||||
// Timers sometimes trigger early (e.g. 1ms to early)
|
||||
assert(now - time >= connect_timeout - 5, 'The real timeout time should be above ' + connect_timeout + 'ms, but it is: ' + (now - time));
|
||||
assert(now - time >= connectTimeout - 5, 'The real timeout time should be above ' + connectTimeout + 'ms, but it is: ' + (now - time));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('use the system socket timeout if the connect_timeout has not been provided', function (done) {
|
||||
it('use the system socket timeout if the connectTimeout has not been provided', function (done) {
|
||||
client = redis.createClient({
|
||||
host: '2001:db8::ff00:42:8329' // auto detect ip v6
|
||||
});
|
||||
assert.strictEqual(client.address, '2001:db8::ff00:42:8329:6379');
|
||||
assert.strictEqual(client.connection_options.family, 6);
|
||||
assert.strictEqual(client.connectionOptions.family, 6);
|
||||
process.nextTick(function () {
|
||||
assert.strictEqual(client.stream.listeners('timeout').length, 0);
|
||||
done();
|
||||
@@ -312,7 +312,7 @@ describe('connection tests', function () {
|
||||
|
||||
it('clears the socket timeout after a connection has been established', function (done) {
|
||||
client = redis.createClient({
|
||||
connect_timeout: 1000
|
||||
connectTimeout: 1000
|
||||
});
|
||||
process.nextTick(function () {
|
||||
assert.strictEqual(client.stream._idleTimeout, 1000);
|
||||
@@ -328,7 +328,7 @@ describe('connection tests', function () {
|
||||
client = redis.createClient({
|
||||
host: 'localhost',
|
||||
port: '6379',
|
||||
connect_timeout: 1000
|
||||
connectTimeout: 1000
|
||||
});
|
||||
|
||||
client.once('ready', done);
|
||||
@@ -340,7 +340,7 @@ describe('connection tests', function () {
|
||||
}
|
||||
client = redis.createClient({
|
||||
path: '/tmp/redis.sock',
|
||||
connect_timeout: 1000
|
||||
connectTimeout: 1000
|
||||
});
|
||||
|
||||
var end = helper.callFuncAfter(done, 2);
|
||||
@@ -371,7 +371,7 @@ describe('connection tests', function () {
|
||||
|
||||
it('connects with a port only', function (done) {
|
||||
client = redis.createClient(6379);
|
||||
assert.strictEqual(client.connection_options.family, 4);
|
||||
assert.strictEqual(client.connectionOptions.family, 4);
|
||||
client.on('error', done);
|
||||
|
||||
client.once('ready', function () {
|
||||
@@ -406,7 +406,7 @@ describe('connection tests', function () {
|
||||
|
||||
it('connects correctly to localhost and no ready check', function (done) {
|
||||
client = redis.createClient(undefined, undefined, {
|
||||
no_ready_check: true
|
||||
noReadyCheck: true
|
||||
});
|
||||
client.on('error', done);
|
||||
|
||||
@@ -421,7 +421,7 @@ describe('connection tests', function () {
|
||||
|
||||
it('connects correctly to the provided host with the port set to undefined', function (done) {
|
||||
client = redis.createClient(undefined, 'localhost', {
|
||||
no_ready_check: true
|
||||
noReadyCheck: true
|
||||
});
|
||||
client.on('error', done);
|
||||
assert.strictEqual(client.address, 'localhost:6379');
|
||||
@@ -442,16 +442,16 @@ describe('connection tests', function () {
|
||||
cb(new Error("ERR unknown command 'info'"));
|
||||
};
|
||||
client.once('ready', function () {
|
||||
assert.strictEqual(Object.keys(client.server_info).length, 0);
|
||||
assert.strictEqual(Object.keys(client.serverInfo).length, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('fake the stream to mock redis', function () {
|
||||
// This is needed for libraries that want to mock the stream like fakeredis
|
||||
var temp = redis.RedisClient.prototype.create_stream;
|
||||
var create_stream_string = String(temp);
|
||||
redis.RedisClient.prototype.create_stream = function () {
|
||||
var temp = redis.RedisClient.prototype.createStream;
|
||||
var createStreamString = String(temp);
|
||||
redis.RedisClient.prototype.createStream = function () {
|
||||
this.connected = true;
|
||||
this.ready = true;
|
||||
};
|
||||
@@ -460,15 +460,15 @@ describe('connection tests', function () {
|
||||
assert.strictEqual(client.ready, true);
|
||||
assert.strictEqual(client.connected, true);
|
||||
client.end = function () {};
|
||||
assert(create_stream_string !== String(redis.RedisClient.prototype.create_stream));
|
||||
redis.RedisClient.prototype.create_stream = temp;
|
||||
assert(create_stream_string === String(redis.RedisClient.prototype.create_stream));
|
||||
assert(createStreamString !== String(redis.RedisClient.prototype.createStream));
|
||||
redis.RedisClient.prototype.createStream = temp;
|
||||
assert(createStreamString === String(redis.RedisClient.prototype.createStream));
|
||||
});
|
||||
|
||||
if (ip === 'IPv4') {
|
||||
it('allows connecting with the redis url to the default host and port, select db 3 and warn about duplicate db option', function (done) {
|
||||
client = redis.createClient('redis:///3?db=3');
|
||||
assert.strictEqual(client.selected_db, '3');
|
||||
assert.strictEqual(client.selectedDb, '3');
|
||||
client.on('ready', done);
|
||||
});
|
||||
|
||||
@@ -484,9 +484,9 @@ describe('connection tests', function () {
|
||||
|
||||
it('allows connecting with the redis url as first parameter and the options as second parameter', function (done) {
|
||||
client = redis.createClient('//127.0.0.1', {
|
||||
connect_timeout: 1000
|
||||
connectTimeout: 1000
|
||||
});
|
||||
assert.strictEqual(client.options.connect_timeout, 1000);
|
||||
assert.strictEqual(client.options.connectTimeout, 1000);
|
||||
client.on('ready', done);
|
||||
});
|
||||
|
||||
@@ -494,8 +494,8 @@ describe('connection tests', function () {
|
||||
client = redis.createClient({
|
||||
url: 'http://foo:porkchopsandwiches@' + config.HOST[ip] + '/3'
|
||||
});
|
||||
assert.strictEqual(client.auth_pass, 'porkchopsandwiches');
|
||||
assert.strictEqual(+client.selected_db, 3);
|
||||
assert.strictEqual(client.authPass, 'porkchopsandwiches');
|
||||
assert.strictEqual(+client.selectedDb, 3);
|
||||
assert(!client.options.port);
|
||||
assert.strictEqual(client.options.host, config.HOST[ip]);
|
||||
client.on('ready', done);
|
||||
@@ -503,7 +503,7 @@ describe('connection tests', function () {
|
||||
|
||||
it('allows connecting with the redis url and no auth and options as second parameter', function (done) {
|
||||
var options = {
|
||||
detect_buffers: false
|
||||
detectBuffers: false
|
||||
};
|
||||
client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT, options);
|
||||
assert.strictEqual(Object.keys(options).length, 1);
|
||||
@@ -512,7 +512,7 @@ describe('connection tests', function () {
|
||||
|
||||
it('allows connecting with the redis url and no auth and options as third parameter', function (done) {
|
||||
client = redis.createClient('redis://' + config.HOST[ip] + ':' + config.PORT, null, {
|
||||
detect_buffers: false
|
||||
detectBuffers: false
|
||||
});
|
||||
client.on('ready', done);
|
||||
});
|
||||
@@ -529,8 +529,8 @@ describe('connection tests', function () {
|
||||
tmp(function (err, res) {
|
||||
if (!delayed) {
|
||||
assert(!err);
|
||||
client.server_info.loading = 1;
|
||||
client.server_info.loading_eta_seconds = 0.5;
|
||||
client.serverInfo.loading = 1;
|
||||
client.serverInfo.loading_eta_seconds = 0.5;
|
||||
delayed = true;
|
||||
time = Date.now();
|
||||
}
|
||||
@@ -560,8 +560,8 @@ describe('connection tests', function () {
|
||||
if (!delayed) {
|
||||
assert(!err);
|
||||
// Try reconnecting after one second even if redis tells us the time needed is above one second
|
||||
client.server_info.loading = 1;
|
||||
client.server_info.loading_eta_seconds = 2.5;
|
||||
client.serverInfo.loading = 1;
|
||||
client.serverInfo.loading_eta_seconds = 2.5;
|
||||
delayed = true;
|
||||
time = Date.now();
|
||||
}
|
||||
|
@@ -5,11 +5,11 @@ var config = require('./lib/config');
|
||||
var helper = require('./helper');
|
||||
var redis = config.redis;
|
||||
|
||||
describe('detect_buffers', function () {
|
||||
describe('detectBuffers', function () {
|
||||
|
||||
var client;
|
||||
var args = config.configureClient('localhost', {
|
||||
detect_buffers: true
|
||||
detectBuffers: true
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
|
@@ -49,7 +49,7 @@ describe('stack traces', function () {
|
||||
// This is always going to return good stack traces
|
||||
it('should always return good stack traces for rejected offline commands', function (done) {
|
||||
var client = redis.createClient({
|
||||
enable_offline_queue: false
|
||||
enableOfflineQueue: false
|
||||
});
|
||||
client.set('foo', function (err, res) {
|
||||
assert(/good_traces.spec.js/.test(err.stack));
|
||||
|
@@ -6,7 +6,7 @@ var config = require('./lib/config');
|
||||
var RedisProcess = require('./lib/redis-process');
|
||||
var StunnelProcess = require('./lib/stunnel-process');
|
||||
var rp;
|
||||
var stunnel_process;
|
||||
var stunnelProcess;
|
||||
|
||||
function startRedis (conf, done, port) {
|
||||
RedisProcess.start(function (err, _rp) {
|
||||
@@ -46,15 +46,15 @@ module.exports = {
|
||||
},
|
||||
startRedis: startRedis,
|
||||
stopStunnel: function (done) {
|
||||
if (stunnel_process) {
|
||||
StunnelProcess.stop(stunnel_process, done);
|
||||
if (stunnelProcess) {
|
||||
StunnelProcess.stop(stunnelProcess, done);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
},
|
||||
startStunnel: function (done) {
|
||||
StunnelProcess.start(function (err, _stunnel_process) {
|
||||
stunnel_process = _stunnel_process;
|
||||
StunnelProcess.start(function (err, _stunnelProcess) {
|
||||
stunnelProcess = _stunnelProcess;
|
||||
return done(err);
|
||||
}, path.resolve(__dirname, './conf'));
|
||||
},
|
||||
@@ -138,18 +138,18 @@ module.exports = {
|
||||
if (done) done();
|
||||
};
|
||||
},
|
||||
serverVersionAtLeast: function (connection, desired_version) {
|
||||
serverVersionAtLeast: function (connection, desiredVersion) {
|
||||
// Wait until a connection has established (otherwise a timeout is going to be triggered at some point)
|
||||
if (Object.keys(connection.server_info).length === 0) {
|
||||
if (Object.keys(connection.serverInfo).length === 0) {
|
||||
throw new Error('Version check not possible as the client is not yet ready or did not expose the version');
|
||||
}
|
||||
// Return true if the server version >= desired_version
|
||||
var version = connection.server_info.versions;
|
||||
// Return true if the server version >= desiredVersion
|
||||
var version = connection.serverInfo.versions;
|
||||
for (var i = 0; i < 3; i++) {
|
||||
if (version[i] > desired_version[i]) {
|
||||
if (version[i] > desiredVersion[i]) {
|
||||
return true;
|
||||
}
|
||||
if (version[i] < desired_version[i]) {
|
||||
if (version[i] < desiredVersion[i]) {
|
||||
if (this.skip) this.skip();
|
||||
return false;
|
||||
}
|
||||
@@ -166,9 +166,9 @@ module.exports = {
|
||||
protocols.push('IPv6', '/tmp/redis.sock');
|
||||
}
|
||||
var options = [{
|
||||
detect_buffers: true
|
||||
detectBuffers: true
|
||||
}, {
|
||||
detect_buffers: false
|
||||
detectBuffers: false
|
||||
}];
|
||||
options.forEach(function (options) {
|
||||
var strOptions = '';
|
||||
@@ -209,7 +209,7 @@ module.exports = {
|
||||
},
|
||||
killConnection: function (client) {
|
||||
// Change the connection option to a non existing one and destroy the stream
|
||||
client.connection_options = {
|
||||
client.connectionOptions = {
|
||||
port: 65535,
|
||||
host: '127.0.0.1',
|
||||
family: 4
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Spawned by the good_stacks.spec.js tests
|
||||
// Spawned by the goodStacks.spec.js tests
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
|
@@ -16,15 +16,15 @@ function once (cb) {
|
||||
};
|
||||
}
|
||||
|
||||
function StunnelProcess (conf_dir) {
|
||||
function StunnelProcess (confDir) {
|
||||
EventEmitter.call(this);
|
||||
|
||||
// set up an stunnel to redis; edit the conf file to include required absolute paths
|
||||
var conf_file = path.resolve(conf_dir, 'stunnel.conf');
|
||||
var conf_text = fs.readFileSync(conf_file + '.template').toString().replace(/__dirname/g, conf_dir);
|
||||
var confFile = path.resolve(confDir, 'stunnel.conf');
|
||||
var confText = fs.readFileSync(confFile + '.template').toString().replace(/__dirname,/g, confDir);
|
||||
|
||||
fs.writeFileSync(conf_file, conf_text);
|
||||
var stunnel = this.stunnel = spawn('stunnel', [conf_file]);
|
||||
fs.writeFileSync(confFile, confText);
|
||||
var stunnel = this.stunnel = spawn('stunnel', [confFile]);
|
||||
|
||||
// handle child process events, and failure to set up tunnel
|
||||
var self = this;
|
||||
@@ -68,9 +68,9 @@ StunnelProcess.prototype.stop = function (done) {
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
start: function (done, conf_dir) {
|
||||
start: function (done, confDir) {
|
||||
done = once(done);
|
||||
var stunnel = new StunnelProcess(conf_dir);
|
||||
var stunnel = new StunnelProcess(confDir);
|
||||
stunnel.once('error', done.bind(done));
|
||||
stunnel.once('started', done.bind(done, null, stunnel));
|
||||
},
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// spawned by the unref tests in node_redis.spec.js.
|
||||
// spawned by the unref tests in nodeRedis.spec.js.
|
||||
// when configured, unref causes the client to exit
|
||||
// as soon as there are no outstanding commands.
|
||||
'use strict';
|
||||
|
@@ -22,8 +22,8 @@ describe("The 'multi' method", function () {
|
||||
var end = helper.callFuncAfter(done, 100);
|
||||
|
||||
// Some random object created from http://beta.json-generator.com/
|
||||
var test_obj = {
|
||||
'_id': '5642c4c33d4667c4a1fefd99', 'index': 0, 'guid': '5baf1f1c-7621-41e7-ae7a-f8c6f3199b0f', 'isActive': true,
|
||||
var testObj = {
|
||||
'Id': '5642c4c33d4667c4a1fefd99', 'index': 0, 'guid': '5baf1f1c-7621-41e7-ae7a-f8c6f3199b0f', 'isActive': true,
|
||||
'balance': '$1,028.63', 'picture': 'http://placehold.it/32x32', 'age': 31, 'eyeColor': 'green', 'name': {'first': 'Shana', 'last': 'Long'},
|
||||
'company': 'MANGLO', 'email': 'shana.long@manglo.us', 'phone': '+1 (926) 405-3105', 'address': '747 Dank Court, Norfolk, Ohio, 1112',
|
||||
'about': 'Eu pariatur in nisi occaecat enim qui consequat nostrud cupidatat id. ' +
|
||||
@@ -38,14 +38,14 @@ describe("The 'multi' method", function () {
|
||||
return;
|
||||
}
|
||||
// To demonstrate a big payload for hash set field values, let's create a big array
|
||||
var test_arr = [];
|
||||
var testArr = [];
|
||||
var i = 0;
|
||||
for (; i < 80; i++) {
|
||||
var new_obj = JSON.parse(JSON.stringify(test_obj));
|
||||
test_arr.push(new_obj);
|
||||
var newObj = JSON.parse(JSON.stringify(testObj));
|
||||
testArr.push(newObj);
|
||||
}
|
||||
|
||||
var json = JSON.stringify(test_arr);
|
||||
var json = JSON.stringify(testArr);
|
||||
zlib.deflate(new Buffer(json), function (err, buffer) {
|
||||
if (err) {
|
||||
done(err);
|
||||
@@ -165,13 +165,13 @@ describe("The 'multi' method", function () {
|
||||
});
|
||||
// Check if Redis still has the error
|
||||
client.monitor();
|
||||
client.send_command('multi');
|
||||
client.send_command('set', ['foo', 'bar']);
|
||||
client.send_command('get', ['foo']);
|
||||
client.send_command('exec', function (err, res) {
|
||||
client.sendCommand('multi');
|
||||
client.sendCommand('set', ['foo', 'bar']);
|
||||
client.sendCommand('get', ['foo']);
|
||||
client.sendCommand('exec', function (err, res) {
|
||||
// res[0] is going to be the monitor result of set
|
||||
// res[1] is going to be the result of the set command
|
||||
assert(utils.monitor_regex.test(res[0]));
|
||||
assert(utils.monitorRegex.test(res[0]));
|
||||
assert.strictEqual(res[1], 'OK');
|
||||
assert.strictEqual(res.length, 2);
|
||||
client.end(false);
|
||||
@@ -184,7 +184,7 @@ describe("The 'multi' method", function () {
|
||||
multi1.set('m1', '123');
|
||||
multi1.get('m1');
|
||||
multi1.exec(done);
|
||||
assert.strictEqual(client.offline_queue.length, 4);
|
||||
assert.strictEqual(client.offlineQueue.length, 4);
|
||||
});
|
||||
|
||||
it('executes a pipelined multi properly after a reconnect in combination with the offline queue', function (done) {
|
||||
@@ -328,15 +328,15 @@ describe("The 'multi' method", function () {
|
||||
multi1.exec(function () {
|
||||
// Redis 2.6.5+ will abort transactions with errors
|
||||
// see: http://redis.io/topics/transactions
|
||||
var multibar_expected = 1;
|
||||
var multifoo_expected = 1;
|
||||
var multibarExpected = 1;
|
||||
var multifooExpected = 1;
|
||||
// Confirm that the previous command, while containing an error, still worked.
|
||||
multi2 = client.multi();
|
||||
multi2.incr('multibar', helper.isNumber(multibar_expected));
|
||||
multi2.incr('multifoo', helper.isNumber(multifoo_expected));
|
||||
multi2.incr('multibar', helper.isNumber(multibarExpected));
|
||||
multi2.incr('multifoo', helper.isNumber(multifooExpected));
|
||||
multi2.exec(function (err, replies) {
|
||||
assert.strictEqual(multibar_expected, replies[0]);
|
||||
assert.strictEqual(multifoo_expected, replies[1]);
|
||||
assert.strictEqual(multibarExpected, replies[0]);
|
||||
assert.strictEqual(multifooExpected, replies[1]);
|
||||
return done();
|
||||
});
|
||||
});
|
||||
@@ -608,20 +608,20 @@ describe("The 'multi' method", function () {
|
||||
client.get('foo', helper.isString('bar', done));
|
||||
});
|
||||
|
||||
it('should not use a transaction with exec_atomic if no command is used', function () {
|
||||
it('should not use a transaction with execAtomic if no command is used', function () {
|
||||
var multi = client.multi();
|
||||
var test = false;
|
||||
multi.exec_batch = function () {
|
||||
multi.execBatch = function () {
|
||||
test = true;
|
||||
};
|
||||
multi.exec_atomic();
|
||||
multi.execAtomic();
|
||||
assert(test);
|
||||
});
|
||||
|
||||
it('should not use a transaction with exec_atomic if only one command is used', function () {
|
||||
it('should not use a transaction with execAtomic if only one command is used', function () {
|
||||
var multi = client.multi();
|
||||
var test = false;
|
||||
multi.exec_batch = function () {
|
||||
multi.execBatch = function () {
|
||||
test = true;
|
||||
};
|
||||
multi.set('baz', 'binary');
|
||||
@@ -629,15 +629,15 @@ describe("The 'multi' method", function () {
|
||||
assert(test);
|
||||
});
|
||||
|
||||
it('should use transaction with exec_atomic and more than one command used', function (done) {
|
||||
it('should use transaction with execAtomic and more than one command used', function (done) {
|
||||
var multi = client.multi();
|
||||
var test = false;
|
||||
multi.exec_batch = function () {
|
||||
multi.execBatch = function () {
|
||||
test = true;
|
||||
};
|
||||
multi.set('baz', 'binary');
|
||||
multi.get('baz');
|
||||
multi.exec_atomic(done);
|
||||
multi.execAtomic(done);
|
||||
assert(!test);
|
||||
});
|
||||
|
||||
@@ -695,23 +695,23 @@ describe("The 'multi' method", function () {
|
||||
// subscribe => enters subscribe mode and this does not work in combination with exec (the same for psubscribe, unsubscribe...)
|
||||
//
|
||||
|
||||
// Make sure send_command is not called
|
||||
client.send_command = function () {
|
||||
// Make sure sendCommand is not called
|
||||
client.sendCommand = function () {
|
||||
throw new Error('failed');
|
||||
};
|
||||
|
||||
assert.strictEqual(client.selected_db, undefined);
|
||||
assert.strictEqual(client.selectedDb, undefined);
|
||||
var multi = client.multi();
|
||||
multi.select(5, function (err, res) {
|
||||
assert.strictEqual(client.selected_db, 5);
|
||||
assert.strictEqual(client.selectedDb, 5);
|
||||
assert.strictEqual(res, 'OK');
|
||||
assert.notDeepEqual(client.server_info.db5, { avg_ttl: 0, expires: 0, keys: 1 });
|
||||
assert.notDeepEqual(client.serverInfo.db5, { avg_ttl: 0, expires: 0, keys: 1 });
|
||||
});
|
||||
// multi.client('reply', 'on', helper.isString('OK')); // Redis v.3.2
|
||||
multi.set('foo', 'bar', helper.isString('OK'));
|
||||
multi.info(function (err, res) {
|
||||
assert.strictEqual(res.indexOf('# Server\r\nredis_version:'), 0);
|
||||
assert.deepEqual(client.server_info.db5, { avg_ttl: 0, expires: 0, keys: 1 });
|
||||
assert.deepEqual(client.serverInfo.db5, { avg_ttl: 0, expires: 0, keys: 1 });
|
||||
});
|
||||
multi.get('foo', helper.isString('bar'));
|
||||
multi.exec(function (err, res) {
|
||||
|
@@ -10,21 +10,21 @@ var fork = require('child_process').fork;
|
||||
var redis = config.redis;
|
||||
var client;
|
||||
|
||||
describe('The node_redis client', function () {
|
||||
describe('The nodeRedis client', function () {
|
||||
|
||||
it('individual commands sanity check', function (done) {
|
||||
// All commands should work the same in multi context or without
|
||||
// Therefor individual commands always have to be handled in both cases
|
||||
fs.readFile(path.resolve(__dirname, '../lib/individualCommands.js'), 'utf8', function (err, data) {
|
||||
var client_prototype = data.match(/(\n| = )RedisClient\.prototype.[a-zA-Z_]+/g);
|
||||
var multi_prototype = data.match(/(\n| = )Multi\.prototype\.[a-zA-Z_]+/g);
|
||||
var clientPrototype = data.match(/(\n| = )RedisClient\.prototype.[a-zA-Z_]+/g);
|
||||
var multiPrototype = data.match(/(\n| = )Multi\.prototype\.[a-zA-Z_]+/g);
|
||||
// Check that every entry RedisClient entry has a correspondend Multi entry
|
||||
assert.strictEqual(client_prototype.filter(function (entry) {
|
||||
return multi_prototype.indexOf(entry.replace('RedisClient', 'Multi')) === -1;
|
||||
assert.strictEqual(clientPrototype.filter(function (entry) {
|
||||
return multiPrototype.indexOf(entry.replace('RedisClient', 'Multi')) === -1;
|
||||
}).length, 4); // multi and batch are included too
|
||||
assert.strictEqual(client_prototype.length, multi_prototype.length + 4);
|
||||
assert.strictEqual(clientPrototype.length, multiPrototype.length + 4);
|
||||
// Check that all entries exist in uppercase and in lowercase variants
|
||||
assert.strictEqual(data.match(/(\n| = )RedisClient\.prototype.[a-z_]+/g).length * 2, client_prototype.length);
|
||||
assert.strictEqual(data.match(/(\n| = )RedisClient\.prototype.[a-z_]+/g).length * 2, clientPrototype.length);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -46,13 +46,13 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
client.once('reconnecting', function () {
|
||||
process.nextTick(function () {
|
||||
assert.strictEqual(client.reply_parser.buffer, null);
|
||||
assert.strictEqual(client.replyParser.buffer, null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
var partialInput = new Buffer('$100\r\nabcdef');
|
||||
client.reply_parser.execute(partialInput);
|
||||
assert.strictEqual(client.reply_parser.buffer.inspect(), partialInput.inspect());
|
||||
client.replyParser.execute(partialInput);
|
||||
assert.strictEqual(client.replyParser.buffer.inspect(), partialInput.inspect());
|
||||
client.stream.destroy();
|
||||
});
|
||||
|
||||
@@ -74,10 +74,10 @@ describe('The node_redis client', function () {
|
||||
|
||||
describe('duplicate', function () {
|
||||
it('check if all options got copied properly', function (done) {
|
||||
client.selected_db = 2;
|
||||
client.selectedDb = 2;
|
||||
var client2 = client.duplicate();
|
||||
assert.strictEqual(client.connectionId + 1, client2.connection_id);
|
||||
assert.strictEqual(client2.selected_db, 2);
|
||||
assert.strictEqual(client.connectionId + 1, client2.connectionId);
|
||||
assert.strictEqual(client2.selectedDb, 2);
|
||||
assert(client.connected);
|
||||
assert(!client2.connected);
|
||||
for (var elem in client.options) {
|
||||
@@ -99,16 +99,16 @@ describe('The node_redis client', function () {
|
||||
|
||||
it('check if all new options replaced the old ones', function (done) {
|
||||
var client2 = client.duplicate({
|
||||
no_ready_check: true
|
||||
noReadyCheck: true
|
||||
});
|
||||
assert(client.connected);
|
||||
assert(!client2.connected);
|
||||
assert.strictEqual(client.options.no_ready_check, undefined);
|
||||
assert.strictEqual(client2.options.no_ready_check, true);
|
||||
assert.strictEqual(client.options.noReadyCheck, undefined);
|
||||
assert.strictEqual(client2.options.noReadyCheck, true);
|
||||
assert.notDeepEqual(client.options, client2.options);
|
||||
for (var elem in client.options) {
|
||||
if (client.options.hasOwnProperty(elem)) {
|
||||
if (elem !== 'no_ready_check') {
|
||||
if (elem !== 'noReadyCheck') {
|
||||
assert.strictEqual(client2.options[elem], client.options[elem]);
|
||||
}
|
||||
}
|
||||
@@ -173,12 +173,12 @@ describe('The node_redis client', function () {
|
||||
str += str;
|
||||
}
|
||||
var called = false;
|
||||
var temp = client.write_buffers.bind(client);
|
||||
assert(client.fire_strings);
|
||||
client.write_buffers = function (data) {
|
||||
var temp = client.writeBuffers.bind(client);
|
||||
assert(client.fireStrings);
|
||||
client.writeBuffers = function (data) {
|
||||
called = true;
|
||||
// To increase write performance for strings the value is converted to a buffer
|
||||
assert(!client.fire_strings);
|
||||
assert(!client.fireStrings);
|
||||
temp(data);
|
||||
};
|
||||
client.multi().set('foo', str).get('foo', function (err, res) {
|
||||
@@ -188,46 +188,46 @@ describe('The node_redis client', function () {
|
||||
assert.strictEqual(res[1], str);
|
||||
done();
|
||||
});
|
||||
assert(client.fire_strings);
|
||||
assert(client.fireStrings);
|
||||
});
|
||||
});
|
||||
|
||||
describe('send_command', function () {
|
||||
describe('sendCommand', function () {
|
||||
|
||||
it('omitting args should be fine', function (done) {
|
||||
client.server_info = {};
|
||||
client.send_command('info');
|
||||
client.send_command('ping', function (err, res) {
|
||||
client.serverInfo = {};
|
||||
client.sendCommand('info');
|
||||
client.sendCommand('ping', function (err, res) {
|
||||
assert.strictEqual(res, 'PONG');
|
||||
// Check if the previous info command used the internal individual info command
|
||||
assert.notDeepEqual(client.server_info, {});
|
||||
client.server_info = {};
|
||||
assert.notDeepEqual(client.serverInfo, {});
|
||||
client.serverInfo = {};
|
||||
});
|
||||
client.send_command('info', null, undefined);
|
||||
client.send_command('ping', null, function (err, res) {
|
||||
client.sendCommand('info', null, undefined);
|
||||
client.sendCommand('ping', null, function (err, res) {
|
||||
assert.strictEqual(res, 'PONG');
|
||||
// Check if the previous info command used the internal individual info command
|
||||
assert.notDeepEqual(client.server_info, {});
|
||||
client.server_info = {};
|
||||
assert.notDeepEqual(client.serverInfo, {});
|
||||
client.serverInfo = {};
|
||||
});
|
||||
client.send_command('info', undefined, undefined);
|
||||
client.send_command('ping', function (err, res) {
|
||||
client.sendCommand('info', undefined, undefined);
|
||||
client.sendCommand('ping', function (err, res) {
|
||||
assert.strictEqual(res, 'PONG');
|
||||
// Check if the previous info command used the internal individual info command
|
||||
assert.notDeepEqual(client.server_info, {});
|
||||
client.server_info = {};
|
||||
assert.notDeepEqual(client.serverInfo, {});
|
||||
client.serverInfo = {};
|
||||
});
|
||||
client.send_command('info', undefined, function (err, res) {
|
||||
client.sendCommand('info', undefined, function (err, res) {
|
||||
assert(/redis_version/.test(res));
|
||||
// The individual info command should also be called by using send_command
|
||||
// console.log(info, client.server_info);
|
||||
assert.notDeepEqual(client.server_info, {});
|
||||
// The individual info command should also be called by using sendCommand
|
||||
// console.log(info, client.serverInfo);
|
||||
assert.notDeepEqual(client.serverInfo, {});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('using multi with sendCommand should work as individual command instead of using the internal multi', function (done) {
|
||||
// This is necessary to keep backwards compatibility and it is the only way to handle multis as you want in node_redis
|
||||
// This is necessary to keep backwards compatibility and it is the only way to handle multis as you want in nodeRedis
|
||||
client.sendCommand('multi');
|
||||
client.sendCommand('set', ['foo', 'bar'], helper.isString('QUEUED'));
|
||||
client.get('foo');
|
||||
@@ -240,9 +240,9 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
|
||||
it('multi should be handled special', function (done) {
|
||||
client.send_command('multi', undefined, helper.isString('OK'));
|
||||
client.sendCommand('multi', undefined, helper.isString('OK'));
|
||||
var args = ['test', 'bla'];
|
||||
client.send_command('set', args, helper.isString('QUEUED'));
|
||||
client.sendCommand('set', args, helper.isString('QUEUED'));
|
||||
assert.deepEqual(args, ['test', 'bla']); // Check args manipulation
|
||||
client.get('test', helper.isString('QUEUED'));
|
||||
client.exec(function (err, res) {
|
||||
@@ -255,13 +255,13 @@ describe('The node_redis client', function () {
|
||||
|
||||
it('using another type as cb should throw', function () {
|
||||
try {
|
||||
client.send_command('set', ['test', 'bla'], [true]);
|
||||
client.sendCommand('set', ['test', 'bla'], [true]);
|
||||
throw new Error('failed');
|
||||
} catch (err) {
|
||||
assert.strictEqual(err.message, 'Wrong input type "Array" for callback function');
|
||||
}
|
||||
try {
|
||||
client.send_command('set', ['test', 'bla'], null);
|
||||
client.sendCommand('set', ['test', 'bla'], null);
|
||||
throw new Error('failed');
|
||||
} catch (err) {
|
||||
assert.strictEqual(err.message, 'Wrong input type "null" for callback function');
|
||||
@@ -270,19 +270,19 @@ describe('The node_redis client', function () {
|
||||
|
||||
it('command argument has to be of type string', function () {
|
||||
try {
|
||||
client.send_command(true, ['test', 'bla'], function () {});
|
||||
client.sendCommand(true, ['test', 'bla'], function () {});
|
||||
throw new Error('failed');
|
||||
} catch (err) {
|
||||
assert.strictEqual(err.message, 'Wrong input type "Boolean" for command name');
|
||||
}
|
||||
try {
|
||||
client.send_command(undefined, ['test', 'bla'], function () {});
|
||||
client.sendCommand(undefined, ['test', 'bla'], function () {});
|
||||
throw new Error('failed');
|
||||
} catch (err) {
|
||||
assert.strictEqual(err.message, 'Wrong input type "undefined" for command name');
|
||||
}
|
||||
try {
|
||||
client.send_command(null, ['test', 'bla'], function () {});
|
||||
client.sendCommand(null, ['test', 'bla'], function () {});
|
||||
throw new Error('failed');
|
||||
} catch (err) {
|
||||
assert.strictEqual(err.message, 'Wrong input type "null" for command name');
|
||||
@@ -291,7 +291,7 @@ describe('The node_redis client', function () {
|
||||
|
||||
it('args may only be of type Array or undefined', function () {
|
||||
try {
|
||||
client.send_command('info', 123);
|
||||
client.sendCommand('info', 123);
|
||||
throw new Error('failed');
|
||||
} catch (err) {
|
||||
assert.strictEqual(err.message, 'Wrong input type "Number" for args');
|
||||
@@ -300,7 +300,7 @@ describe('The node_redis client', function () {
|
||||
|
||||
it('passing a callback as args and as callback should throw', function () {
|
||||
try {
|
||||
client.send_command('info', function a () {}, function b () {});
|
||||
client.sendCommand('info', function a () {}, function b () {});
|
||||
throw new Error('failed');
|
||||
} catch (err) {
|
||||
assert.strictEqual(err.message, 'Wrong input type "Function" for args');
|
||||
@@ -308,9 +308,9 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
|
||||
it('multi should be handled special', function (done) {
|
||||
client.send_command('multi', undefined, helper.isString('OK'));
|
||||
client.sendCommand('multi', undefined, helper.isString('OK'));
|
||||
var args = ['test', 'bla'];
|
||||
client.send_command('set', args, helper.isString('QUEUED'));
|
||||
client.sendCommand('set', args, helper.isString('QUEUED'));
|
||||
assert.deepEqual(args, ['test', 'bla']); // Check args manipulation
|
||||
client.get('test', helper.isString('QUEUED'));
|
||||
client.exec(function (err, res) {
|
||||
@@ -322,7 +322,7 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
|
||||
it('the args array may contain a arbitrary number of arguments', function (done) {
|
||||
client.send_command('mset', ['foo', 1, 'bar', 2, 'baz', 3], helper.isString('OK'));
|
||||
client.sendCommand('mset', ['foo', 1, 'bar', 2, 'baz', 3], helper.isString('OK'));
|
||||
client.mget(['foo', 'bar', 'baz'], function (err, res) {
|
||||
// As the multi command is handled individually by the user he also has to handle the return value
|
||||
assert.strictEqual(res[0].toString(), '1');
|
||||
@@ -332,8 +332,8 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('send_command with callback as args', function (done) {
|
||||
client.send_command('abcdef', function (err, res) {
|
||||
it('sendCommand with callback as args', function (done) {
|
||||
client.sendCommand('abcdef', function (err, res) {
|
||||
assert.strictEqual(err.message, "ERR unknown command 'abcdef'");
|
||||
done();
|
||||
});
|
||||
@@ -341,11 +341,11 @@ describe('The node_redis client', function () {
|
||||
|
||||
});
|
||||
|
||||
describe('retry_unfulfilled_commands', function () {
|
||||
describe('retryUnfulfilledCommands', function () {
|
||||
|
||||
it('should retry all commands instead of returning an error if a command did not yet return after a connection loss', function (done) {
|
||||
var bclient = redis.createClient({
|
||||
retry_unfulfilled_commands: true
|
||||
retryUnfulfilledCommands: true
|
||||
});
|
||||
bclient.blpop('blocking list 2', 5, function (err, value) {
|
||||
assert.strictEqual(value[0], 'blocking list 2');
|
||||
@@ -426,8 +426,8 @@ describe('The node_redis client', function () {
|
||||
}
|
||||
});
|
||||
|
||||
it('emits an aggregate error if no callback was present for multiple commands in debug_mode', function (done) {
|
||||
redis.debug_mode = true;
|
||||
it('emits an aggregate error if no callback was present for multiple commands in debugMode', function (done) {
|
||||
redis.debugMode = true;
|
||||
var unhookIntercept = intercept(function (data) {
|
||||
return ''; // Don't print the debug messages
|
||||
});
|
||||
@@ -449,11 +449,11 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
client.end(true);
|
||||
unhookIntercept();
|
||||
redis.debug_mode = false;
|
||||
redis.debugMode = false;
|
||||
});
|
||||
|
||||
it('emits an abort error if no callback was present for a single commands', function (done) {
|
||||
redis.debug_mode = true;
|
||||
redis.debugMode = true;
|
||||
var unhookIntercept = intercept(function (data) {
|
||||
return ''; // Don't print the debug messages
|
||||
});
|
||||
@@ -470,10 +470,10 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
client.end(true);
|
||||
unhookIntercept();
|
||||
redis.debug_mode = false;
|
||||
redis.debugMode = false;
|
||||
});
|
||||
|
||||
it('does not emit abort errors if no callback was present while not being in debug_mode ', function (done) {
|
||||
it('does not emit abort errors if no callback was present while not being in debugMode ', function (done) {
|
||||
client.set('foo', 'bar');
|
||||
client.end(true);
|
||||
setTimeout(done, 100);
|
||||
@@ -492,7 +492,7 @@ describe('The node_redis client', function () {
|
||||
client.quit(function () {
|
||||
client.get('foo', function (err, res) {
|
||||
assert.strictEqual(err.message, 'Stream connection ended and command aborted. It might have been processed.');
|
||||
assert.strictEqual(client.offline_queue.length, 0);
|
||||
assert.strictEqual(client.offlineQueue.length, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -506,7 +506,7 @@ describe('The node_redis client', function () {
|
||||
client.get('foo', function (err, res) {
|
||||
assert.strictEqual(err.message, 'GET can\'t be processed. The connection is already closed.');
|
||||
assert.strictEqual(err.command, 'GET');
|
||||
assert.strictEqual(client.offline_queue.length, 0);
|
||||
assert.strictEqual(client.offlineQueue.length, 0);
|
||||
done();
|
||||
});
|
||||
}, 50);
|
||||
@@ -518,7 +518,7 @@ describe('The node_redis client', function () {
|
||||
client.on('error', function (err) {
|
||||
assert.strictEqual(err.message, 'SET can\'t be processed. The connection is already closed.');
|
||||
assert.strictEqual(err.command, 'SET');
|
||||
assert.strictEqual(client.offline_queue_length, 0);
|
||||
assert.strictEqual(client.offlineQueue.length, 0);
|
||||
done();
|
||||
});
|
||||
setTimeout(function () {
|
||||
@@ -530,13 +530,13 @@ describe('The node_redis client', function () {
|
||||
|
||||
describe('when redis closes unexpectedly', function () {
|
||||
it('reconnects and can retrieve the pre-existing data', function (done) {
|
||||
client.on('reconnecting', function on_recon (params) {
|
||||
client.on('connect', function on_connect () {
|
||||
client.on('reconnecting', function onRecon (params) {
|
||||
client.on('connect', function onConnect () {
|
||||
var end = helper.callFuncAfter(function () {
|
||||
client.removeListener('connect', on_connect);
|
||||
client.removeListener('reconnecting', on_recon);
|
||||
assert.strictEqual(client.server_info.db0.keys, 2);
|
||||
assert.strictEqual(Object.keys(client.server_info.db0).length, 3);
|
||||
client.removeListener('connect', onConnect);
|
||||
client.removeListener('reconnecting', onRecon);
|
||||
assert.strictEqual(client.serverInfo.db0.keys, 2);
|
||||
assert.strictEqual(Object.keys(client.serverInfo.db0).length, 3);
|
||||
done();
|
||||
}, 4);
|
||||
client.get('recon 1', helper.isString('one', end));
|
||||
@@ -555,11 +555,11 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
|
||||
it('reconnects properly when monitoring', function (done) {
|
||||
client.on('reconnecting', function on_recon (params) {
|
||||
client.on('ready', function on_ready () {
|
||||
client.on('reconnecting', function onRecon (params) {
|
||||
client.on('ready', function onReady () {
|
||||
assert.strictEqual(client.monitoring, true, 'monitoring after reconnect');
|
||||
client.removeListener('ready', on_ready);
|
||||
client.removeListener('reconnecting', on_recon);
|
||||
client.removeListener('ready', onReady);
|
||||
client.removeListener('reconnecting', onRecon);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -579,7 +579,7 @@ describe('The node_redis client', function () {
|
||||
describe("and it's subscribed to a channel", function () {
|
||||
// "Connection in subscriber mode, only subscriber commands may be used"
|
||||
it('reconnects, unsubscribes, and can retrieve the pre-existing data', function (done) {
|
||||
client.on('ready', function on_connect () {
|
||||
client.on('ready', function onConnect () {
|
||||
client.unsubscribe(helper.isNotError());
|
||||
|
||||
client.on('unsubscribe', function (channel, count) {
|
||||
@@ -599,7 +599,7 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
|
||||
it('reconnects, unsubscribes, and can retrieve the pre-existing data of a explicit channel', function (done) {
|
||||
client.on('ready', function on_connect () {
|
||||
client.on('ready', function onConnect () {
|
||||
client.unsubscribe('recon channel', helper.isNotError());
|
||||
|
||||
client.on('unsubscribe', function (channel, count) {
|
||||
@@ -709,7 +709,7 @@ describe('The node_redis client', function () {
|
||||
monitorClient.on('monitor', function (time, args, rawOutput) {
|
||||
assert.strictEqual(monitorClient.monitoring, true);
|
||||
responses.push(args);
|
||||
assert(utils.monitor_regex.test(rawOutput), rawOutput);
|
||||
assert(utils.monitorRegex.test(rawOutput), rawOutput);
|
||||
if (responses.length === 6) {
|
||||
assert.deepEqual(responses[0], ['mget', 'some', 'keys', 'foo', 'bar']);
|
||||
assert.deepEqual(responses[1], ['set', 'json', '{"foo":"123","bar":"sdflkdfsjk","another":false}']);
|
||||
@@ -722,9 +722,9 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('monitors returns strings in the rawOutput even with return_buffers activated', function (done) {
|
||||
it('monitors returns strings in the rawOutput even with returnBuffers activated', function (done) {
|
||||
var monitorClient = redis.createClient({
|
||||
return_buffers: true
|
||||
returnBuffers: true
|
||||
});
|
||||
|
||||
monitorClient.MONITOR(function (err, res) {
|
||||
@@ -735,7 +735,7 @@ describe('The node_redis client', function () {
|
||||
|
||||
monitorClient.on('monitor', function (time, args, rawOutput) {
|
||||
assert.strictEqual(typeof rawOutput, 'string');
|
||||
assert(utils.monitor_regex.test(rawOutput), rawOutput);
|
||||
assert(utils.monitorRegex.test(rawOutput), rawOutput);
|
||||
assert.deepEqual(args, ['mget', 'hello', 'world']);
|
||||
// Quit immediatly ends monitoring mode and therefore does not stream back the quit command
|
||||
monitorClient.quit(done);
|
||||
@@ -748,7 +748,7 @@ describe('The node_redis client', function () {
|
||||
client.mget('hello', 'world');
|
||||
client.on('monitor', function (time, args, rawOutput) {
|
||||
assert.strictEqual(client.monitoring, true);
|
||||
assert(utils.monitor_regex.test(rawOutput), rawOutput);
|
||||
assert(utils.monitorRegex.test(rawOutput), rawOutput);
|
||||
assert.deepEqual(args, ['mget', 'hello', 'world']);
|
||||
if (i++ === 2) {
|
||||
// End after two reconnects
|
||||
@@ -769,7 +769,7 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
client.on('monitor', function (time, args, rawOutput) {
|
||||
assert.strictEqual(client.monitoring, true);
|
||||
assert(utils.monitor_regex.test(rawOutput), rawOutput);
|
||||
assert(utils.monitorRegex.test(rawOutput), rawOutput);
|
||||
assert.deepEqual(args, ['mget', 'hello', 'world']);
|
||||
if (i++ === 2) {
|
||||
// End after two reconnects
|
||||
@@ -822,7 +822,7 @@ describe('The node_redis client', function () {
|
||||
var called = false;
|
||||
client.on('monitor', function (time, args, rawOutput) {
|
||||
responses.push(args);
|
||||
assert(utils.monitor_regex.test(rawOutput), rawOutput);
|
||||
assert(utils.monitorRegex.test(rawOutput), rawOutput);
|
||||
if (responses.length === 7) {
|
||||
assert.deepEqual(responses[0], ['subscribe', '/foo', '/bar']);
|
||||
assert.deepEqual(responses[1], ['unsubscribe', '/bar']);
|
||||
@@ -851,10 +851,10 @@ describe('The node_redis client', function () {
|
||||
|
||||
describe('utf8', function () {
|
||||
it('handles utf-8 keys', function (done) {
|
||||
var utf8_sample = 'ಠ_ಠ';
|
||||
client.set(['utf8test', utf8_sample], helper.isString('OK'));
|
||||
var utf8Sample = 'ಠ_ಠ';
|
||||
client.set(['utf8test', utf8Sample], helper.isString('OK'));
|
||||
client.get(['utf8test'], function (err, obj) {
|
||||
assert.strictEqual(utf8_sample, obj);
|
||||
assert.strictEqual(utf8Sample, obj);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
@@ -904,14 +904,14 @@ describe('The node_redis client', function () {
|
||||
// assert(fired);
|
||||
// done();
|
||||
// });
|
||||
// assert.strictEqual(client.offline_queue.length, 1);
|
||||
// assert.strictEqual(client.command_queue.length, 1);
|
||||
// assert.strictEqual(client.offlineQueue.length, 1);
|
||||
// assert.strictEqual(client.commandQueue.length, 1);
|
||||
// client.on('connect', function () {
|
||||
// assert.strictEqual(client.offline_queue.length, 1);
|
||||
// assert.strictEqual(client.command_queue.length, 1);
|
||||
// assert.strictEqual(client.offlineQueue.length, 1);
|
||||
// assert.strictEqual(client.commandQueue.length, 1);
|
||||
// });
|
||||
// client.on('ready', function () {
|
||||
// assert.strictEqual(client.offline_queue.length, 0);
|
||||
// assert.strictEqual(client.offlineQueue.length, 0);
|
||||
// });
|
||||
// });
|
||||
});
|
||||
@@ -942,13 +942,13 @@ describe('The node_redis client', function () {
|
||||
// ready is called in a reply
|
||||
process.nextTick(function () {
|
||||
// Fail the set answer. Has no corresponding command obj and will therefore land in the error handler and set
|
||||
client.reply_parser.execute(new Buffer('a*1\r*1\r$1`zasd\r\na'));
|
||||
client.replyParser.execute(new Buffer('a*1\r*1\r$1`zasd\r\na'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('enable_offline_queue', function () {
|
||||
describe('enableOfflineQueue', function () {
|
||||
describe('true', function () {
|
||||
it('does not return an error and enqueues operation', function (done) {
|
||||
client = redis.createClient(9999);
|
||||
@@ -964,7 +964,7 @@ describe('The node_redis client', function () {
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
assert.strictEqual(client.offline_queue.length, 1);
|
||||
assert.strictEqual(client.offlineQueue.length, 1);
|
||||
finished = true;
|
||||
done();
|
||||
}, 25);
|
||||
@@ -974,6 +974,7 @@ describe('The node_redis client', function () {
|
||||
it.skip('enqueues operation and keep the queue while trying to reconnect', function (done) {
|
||||
client = redis.createClient(9999, null, {
|
||||
retryStrategy: function (options) {
|
||||
console.log(options)
|
||||
if (options.attempt < 4) {
|
||||
return 200;
|
||||
}
|
||||
@@ -984,7 +985,7 @@ describe('The node_redis client', function () {
|
||||
client.on('error', function (err) {
|
||||
if (err.code === 'CONNECTION_BROKEN') {
|
||||
assert(i, 3);
|
||||
assert.strictEqual(client.offline_queue.length, 0);
|
||||
assert.strictEqual(client.offlineQueue.length, 0);
|
||||
assert.strictEqual(err.origin.code, 'ECONNREFUSED');
|
||||
if (!(err instanceof redis.AbortError)) {
|
||||
done();
|
||||
@@ -1001,10 +1002,10 @@ describe('The node_redis client', function () {
|
||||
client.on('reconnecting', function (params) {
|
||||
i++;
|
||||
assert.equal(params.attempt, i);
|
||||
assert.strictEqual(params.times_connected, 0);
|
||||
assert.strictEqual(params.timesConnected, 0);
|
||||
assert(params.error instanceof Error);
|
||||
assert(typeof params.total_retry_time === 'number');
|
||||
assert.strictEqual(client.offline_queue.length, 2);
|
||||
assert(typeof params.totalRetryTime === 'number');
|
||||
assert.strictEqual(client.offlineQueue.length, 2);
|
||||
});
|
||||
|
||||
// Should work with either a callback or without
|
||||
@@ -1012,7 +1013,7 @@ describe('The node_redis client', function () {
|
||||
client.set('foo', 'bar', function (err, result) {
|
||||
assert(i, 3);
|
||||
assert(err);
|
||||
assert.strictEqual(client.offline_queue.length, 0);
|
||||
assert.strictEqual(client.offlineQueue.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1031,20 +1032,20 @@ describe('The node_redis client', function () {
|
||||
multi.set('foo' + (i + 2), 'bar' + (i + 2));
|
||||
}
|
||||
multi.exec();
|
||||
assert.equal(client.command_queue_length, 15);
|
||||
assert.equal(client.commandQueue.length, 15);
|
||||
helper.killConnection(client);
|
||||
});
|
||||
|
||||
var end = helper.callFuncAfter(done, 3);
|
||||
client.on('error', function (err) {
|
||||
if (err.command === 'EXEC') {
|
||||
assert.strictEqual(client.command_queue.length, 0);
|
||||
assert.strictEqual(client.commandQueue.length, 0);
|
||||
assert.strictEqual(err.errors.length, 9);
|
||||
assert.strictEqual(err.errors[1].command, 'SET');
|
||||
assert.deepEqual(err.errors[1].args, ['foo1', 'bar1']);
|
||||
end();
|
||||
} else if (err.code === 'UNCERTAIN_STATE') {
|
||||
assert.strictEqual(client.command_queue.length, 0);
|
||||
assert.strictEqual(client.commandQueue.length, 0);
|
||||
assert.strictEqual(err.errors.length, 4);
|
||||
assert.strictEqual(err.errors[0].command, 'SET');
|
||||
assert.deepEqual(err.errors[0].args, ['foo0', 'bar0']);
|
||||
@@ -1063,7 +1064,7 @@ describe('The node_redis client', function () {
|
||||
|
||||
it('stream not writable', function (done) {
|
||||
client = redis.createClient({
|
||||
enable_offline_queue: false
|
||||
enableOfflineQueue: false
|
||||
});
|
||||
client.on('ready', function () {
|
||||
client.stream.destroy();
|
||||
@@ -1076,13 +1077,13 @@ describe('The node_redis client', function () {
|
||||
|
||||
it('emit an error and does not enqueues operation', function (done) {
|
||||
client = redis.createClient(9999, null, {
|
||||
enable_offline_queue: false
|
||||
enableOfflineQueue: false
|
||||
});
|
||||
var end = helper.callFuncAfter(done, 3);
|
||||
|
||||
client.on('error', function (err) {
|
||||
assert(/offline queue is deactivated|ECONNREFUSED/.test(err.message));
|
||||
assert.equal(client.command_queue.length, 0);
|
||||
assert.equal(client.commandQueue.length, 0);
|
||||
end();
|
||||
});
|
||||
|
||||
@@ -1099,10 +1100,10 @@ describe('The node_redis client', function () {
|
||||
|
||||
it('flushes the command queue if connection is lost', function (done) {
|
||||
client = redis.createClient({
|
||||
enable_offline_queue: false
|
||||
enableOfflineQueue: false
|
||||
});
|
||||
|
||||
redis.debug_mode = true;
|
||||
redis.debugMode = true;
|
||||
var unhookIntercept = intercept(function () {
|
||||
return '';
|
||||
});
|
||||
@@ -1118,13 +1119,13 @@ describe('The node_redis client', function () {
|
||||
multi.set('foo' + (i + 2), 'bar' + (i + 2));
|
||||
}
|
||||
multi.exec();
|
||||
assert.equal(client.command_queue.length, 15);
|
||||
assert.equal(client.commandQueue.length, 15);
|
||||
helper.killConnection(client);
|
||||
});
|
||||
|
||||
var end = helper.callFuncAfter(done, 3);
|
||||
client.on('error', function (err) {
|
||||
assert.equal(client.command_queue.length, 0);
|
||||
assert.equal(client.commandQueue.length, 0);
|
||||
if (err.command === 'EXEC') {
|
||||
assert.equal(err.errors.length, 9);
|
||||
end();
|
||||
@@ -1135,7 +1136,7 @@ describe('The node_redis client', function () {
|
||||
assert.equal(err.code, 'ECONNREFUSED');
|
||||
assert.equal(err.errno, 'ECONNREFUSED');
|
||||
assert.equal(err.syscall, 'connect');
|
||||
redis.debug_mode = false;
|
||||
redis.debugMode = false;
|
||||
client.end(true);
|
||||
unhookIntercept();
|
||||
end();
|
||||
|
@@ -35,7 +35,7 @@ describe('publish/subscribe', function () {
|
||||
beforeEach(function (done) {
|
||||
sub.end(false);
|
||||
sub = redis.createClient({
|
||||
disable_resubscribing: true
|
||||
disableResubscribing: true
|
||||
});
|
||||
sub.once('connect', function () {
|
||||
done();
|
||||
@@ -57,7 +57,7 @@ describe('publish/subscribe', function () {
|
||||
sub.on('reconnecting', function () {
|
||||
a = true;
|
||||
sub.on('ready', function () {
|
||||
assert.strictEqual(sub.command_queue.length, 0);
|
||||
assert.strictEqual(sub.commandQueue.length, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -66,11 +66,11 @@ describe('publish/subscribe', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('string_numbers and pub sub', function () {
|
||||
describe('stringNumbers and pub sub', function () {
|
||||
beforeEach(function (done) {
|
||||
sub.end(false);
|
||||
sub = redis.createClient({
|
||||
string_numbers: true
|
||||
stringNumbers: true
|
||||
});
|
||||
sub.once('connect', function () {
|
||||
done();
|
||||
@@ -90,8 +90,8 @@ describe('publish/subscribe', function () {
|
||||
});
|
||||
sub.subscribe(channel, channel2);
|
||||
sub.unsubscribe(function (err, res) { // Do not pass a channel here!
|
||||
assert.strictEqual(sub.pub_sub_mode, 2);
|
||||
assert.deepEqual(sub.subscription_set, {});
|
||||
assert.strictEqual(sub.pubSubMode, 2);
|
||||
assert.deepEqual(sub.subscriptionSet, {});
|
||||
end();
|
||||
});
|
||||
sub.set('foo', 'bar', helper.isString('OK'));
|
||||
@@ -121,7 +121,7 @@ describe('publish/subscribe', function () {
|
||||
var a = false;
|
||||
sub.end(true);
|
||||
sub = redis.createClient({
|
||||
detect_buffers: true
|
||||
detectBuffers: true
|
||||
});
|
||||
sub.on('subscribe', function (chnl, count) {
|
||||
if (chnl.inspect() === new Buffer([0xAA, 0xBB, 0x00, 0xF0]).inspect()) {
|
||||
@@ -178,7 +178,7 @@ describe('publish/subscribe', function () {
|
||||
sub.subscribe(channel);
|
||||
});
|
||||
|
||||
it('handles SUB_UNSUB_MSG_SUB', function (done) {
|
||||
it('handles SUB UNSUB MSG SUB', function (done) {
|
||||
sub.subscribe('chan8');
|
||||
sub.subscribe('chan9');
|
||||
sub.unsubscribe('chan9');
|
||||
@@ -186,7 +186,7 @@ describe('publish/subscribe', function () {
|
||||
sub.subscribe('chan9', done);
|
||||
});
|
||||
|
||||
it('handles SUB_UNSUB_MSG_SUB 2', function (done) {
|
||||
it('handles SUB UNSUB MSG SUB 2', function (done) {
|
||||
sub.psubscribe('abc*', helper.isString('abc*'));
|
||||
sub.subscribe('xyz');
|
||||
sub.unsubscribe('xyz');
|
||||
@@ -263,7 +263,7 @@ describe('publish/subscribe', function () {
|
||||
|
||||
it('handles multiple channels with the same channel name properly, even with buffers', function (done) {
|
||||
var channels = ['a', 'b', 'a', new Buffer('a'), 'c', 'b'];
|
||||
var subscribed_channels = [1, 2, 2, 2, 3, 3];
|
||||
var subscribedChannels = [1, 2, 2, 2, 3, 3];
|
||||
var i = 0;
|
||||
sub.subscribe(channels);
|
||||
sub.on('subscribe', function (channel, count) {
|
||||
@@ -272,7 +272,7 @@ describe('publish/subscribe', function () {
|
||||
} else {
|
||||
assert.strictEqual(channel, channels[i].toString());
|
||||
}
|
||||
assert.strictEqual(count, subscribed_channels[i]);
|
||||
assert.strictEqual(count, subscribedChannels[i]);
|
||||
i++;
|
||||
});
|
||||
sub.unsubscribe('a', 'c', 'b');
|
||||
@@ -486,24 +486,25 @@ describe('publish/subscribe', function () {
|
||||
|
||||
describe('psubscribe', function () {
|
||||
it('allows all channels to be subscribed to using a * pattern', function (done) {
|
||||
sub.subscribe('/foo');
|
||||
var sub2 = redis.createClient({
|
||||
return_buffers: true
|
||||
returnBuffers: true
|
||||
});
|
||||
sub2.on('ready', function () {
|
||||
sub2.batch().psubscribe('*', helper.isString('*')).exec();
|
||||
sub2.subscribe('/foo');
|
||||
sub2.on('pmessage', function (pattern, channel, message) {
|
||||
assert.strictEqual(pattern.inspect(), new Buffer('*').inspect());
|
||||
assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect());
|
||||
assert.strictEqual(message.inspect(), new Buffer('hello world').inspect());
|
||||
sub2.quit(done);
|
||||
sub.subscribe('/foo', function () {
|
||||
sub2.on('ready', function () {
|
||||
sub2.batch().psubscribe('*', helper.isString('*')).exec();
|
||||
sub2.subscribe('/foo');
|
||||
sub2.on('pmessage', function (pattern, channel, message) {
|
||||
assert.strictEqual(pattern.inspect(), new Buffer('*').inspect());
|
||||
assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect());
|
||||
assert.strictEqual(message.inspect(), new Buffer('hello world').inspect());
|
||||
sub2.quit(done);
|
||||
});
|
||||
pub.pubsub('numsub', '/foo', function (err, res) {
|
||||
assert.deepEqual(res, ['/foo', 2]);
|
||||
});
|
||||
// sub2 is counted twice as it subscribed with psubscribe and subscribe
|
||||
pub.publish('/foo', 'hello world', helper.isNumber(3));
|
||||
});
|
||||
pub.pubsub('numsub', '/foo', function (err, res) {
|
||||
assert.deepEqual(res, ['/foo', 2]);
|
||||
});
|
||||
// sub2 is counted twice as it subscribed with psubscribe and subscribe
|
||||
pub.publish('/foo', 'hello world', helper.isNumber(3));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -513,21 +514,14 @@ describe('publish/subscribe', function () {
|
||||
sub.set('foo', data, function () {
|
||||
sub.get('foo');
|
||||
sub.stream.once('data', function () {
|
||||
assert.strictEqual(sub.message_buffers, false);
|
||||
assert.strictEqual(sub.messageBuffers, false);
|
||||
assert.strictEqual(sub.shouldBuffer, false);
|
||||
sub.on('pmessageBuffer', function (pattern, channel, message) {
|
||||
if (parser !== 'javascript' && typeof pattern === 'string') {
|
||||
pattern = new Buffer(pattern);
|
||||
channel = new Buffer(channel);
|
||||
}
|
||||
assert.strictEqual(pattern.inspect(), new Buffer('*').inspect());
|
||||
assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect());
|
||||
sub.quit(end);
|
||||
});
|
||||
if (parser === 'javascript') {
|
||||
assert.notStrictEqual(sub.message_buffers, sub.buffers);
|
||||
}
|
||||
|
||||
assert.notStrictEqual(sub.messageBuffers, sub.buffers);
|
||||
});
|
||||
var batch = sub.batch();
|
||||
batch.psubscribe('*');
|
||||
@@ -553,7 +547,7 @@ describe('publish/subscribe', function () {
|
||||
});
|
||||
pub.publish('/foo', 'hello world', helper.isNumber(2));
|
||||
});
|
||||
// Either message_buffers or buffers has to be true, but not both at the same time
|
||||
// Either messageBuffers or buffers has to be true, but not both at the same time
|
||||
sub.on('pmessage', function (pattern, channel, message) {
|
||||
assert.strictEqual(pattern, '*');
|
||||
assert.strictEqual(channel, '/foo');
|
||||
|
@@ -25,7 +25,7 @@ describe('rename commands', function () {
|
||||
beforeEach(function (done) {
|
||||
if (helper.redisProcess().spawnFailed()) return done();
|
||||
client = redis.createClient({
|
||||
rename_commands: {
|
||||
renameCommands: {
|
||||
set: '807081f5afa96845a02816a28b7258c3',
|
||||
GETRANGE: '9e3102b15cf231c4e9e940f284744fe0'
|
||||
}
|
||||
@@ -120,7 +120,7 @@ describe('rename commands', function () {
|
||||
|
||||
client.end(true);
|
||||
client = redis.createClient({
|
||||
rename_commands: {
|
||||
renameCommands: {
|
||||
set: '807081f5afa96845a02816a28b7258c3'
|
||||
},
|
||||
prefix: 'baz'
|
||||
|
@@ -5,29 +5,29 @@ var config = require('./lib/config');
|
||||
var helper = require('./helper');
|
||||
var redis = config.redis;
|
||||
|
||||
describe('return_buffers', function () {
|
||||
describe('returnBuffers', function () {
|
||||
|
||||
helper.allTests(function (ip, basicArgs) {
|
||||
|
||||
describe('using ' + ip, function () {
|
||||
var client;
|
||||
var args = config.configureClient(ip, {
|
||||
return_buffers: true,
|
||||
detect_buffers: true
|
||||
returnBuffers: true,
|
||||
detectBuffers: true
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
client = redis.createClient.apply(null, args);
|
||||
var i = 1;
|
||||
if (args[2].detect_buffers) {
|
||||
// Test if detect_buffer option was deactivated
|
||||
assert.strictEqual(client.options.detect_buffers, false);
|
||||
args[2].detect_buffers = false;
|
||||
if (args[2].detectBuffers) {
|
||||
// Test if detectBuffer option was deactivated
|
||||
assert.strictEqual(client.options.detectBuffers, false);
|
||||
args[2].detectBuffers = false;
|
||||
i++;
|
||||
}
|
||||
var end = helper.callFuncAfter(done, i);
|
||||
client.on('warning', function (msg) {
|
||||
assert.strictEqual(msg, 'WARNING: You activated return_buffers and detect_buffers at the same time. The return value is always going to be a buffer.');
|
||||
assert.strictEqual(msg, 'WARNING: You activated returnBuffers and detectBuffers at the same time. The return value is always going to be a buffer.');
|
||||
end();
|
||||
});
|
||||
client.once('error', done);
|
||||
@@ -244,7 +244,7 @@ describe('return_buffers', function () {
|
||||
var message = new Buffer('test message');
|
||||
|
||||
var args = config.configureClient(ip, {
|
||||
return_buffers: true
|
||||
returnBuffers: true
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
|
@@ -8,20 +8,20 @@ var path = require('path');
|
||||
var redis = config.redis;
|
||||
var utils = require('../lib/utils');
|
||||
|
||||
var tls_options = {
|
||||
var tlsOptions = {
|
||||
servername: 'redis.js.org',
|
||||
rejectUnauthorized: true,
|
||||
ca: [ String(fs.readFileSync(path.resolve(__dirname, './conf/redis.js.org.cert'))) ]
|
||||
};
|
||||
|
||||
var tls_port = 6380;
|
||||
var tlsPort = 6380;
|
||||
// Use skip instead of returning to indicate what tests really got skipped
|
||||
var skip = false;
|
||||
|
||||
// Wait until stunnel4 is in the travis whitelist
|
||||
// Check: https://github.com/travis-ci/apt-package-whitelist/issues/403
|
||||
// If this is merged, remove the travis env checks
|
||||
describe('TLS connection tests', function () {
|
||||
describe.skip('TLS connection tests', function () {
|
||||
|
||||
before(function (done) {
|
||||
// Print the warning when the tests run instead of while starting mocha
|
||||
@@ -53,14 +53,14 @@ describe('TLS connection tests', function () {
|
||||
describe('on lost connection', function () {
|
||||
it.skip('emit an error after max retry timeout and do not try to reconnect afterwards', function (done) {
|
||||
if (skip) this.skip();
|
||||
var connect_timeout = 500; // in ms
|
||||
var connectTimeout = 500; // in ms
|
||||
client = redis.createClient({
|
||||
connect_timeout: connect_timeout,
|
||||
port: tls_port,
|
||||
tls: tls_options
|
||||
connectTimeout: connectTimeout,
|
||||
port: tlsPort,
|
||||
tls: tlsOptions
|
||||
});
|
||||
var time = 0;
|
||||
assert.strictEqual(client.address, '127.0.0.1:' + tls_port);
|
||||
assert.strictEqual(client.address, '127.0.0.1:' + tlsPort);
|
||||
|
||||
client.once('ready', function () {
|
||||
helper.killConnection(client);
|
||||
@@ -73,12 +73,12 @@ describe('TLS connection tests', function () {
|
||||
client.on('error', function (err) {
|
||||
if (/Redis connection in broken state: connection timeout.*?exceeded./.test(err.message)) {
|
||||
process.nextTick(function () {
|
||||
assert.strictEqual(time, connect_timeout);
|
||||
assert.strictEqual(client.emitted_end, true);
|
||||
assert.strictEqual(time, connectTimeout);
|
||||
assert.strictEqual(client.emittedEnd, true);
|
||||
assert.strictEqual(client.connected, false);
|
||||
assert.strictEqual(client.ready, false);
|
||||
assert.strictEqual(client.closing, true);
|
||||
assert.strictEqual(time, connect_timeout);
|
||||
assert.strictEqual(time, connectTimeout);
|
||||
done();
|
||||
});
|
||||
}
|
||||
@@ -90,18 +90,18 @@ describe('TLS connection tests', function () {
|
||||
|
||||
it('connect with host and port provided in the tls object', function (done) {
|
||||
if (skip) this.skip();
|
||||
var tls = utils.clone(tls_options);
|
||||
tls.port = tls_port;
|
||||
var tls = utils.clone(tlsOptions);
|
||||
tls.port = tlsPort;
|
||||
tls.host = 'localhost';
|
||||
client = redis.createClient({
|
||||
connect_timeout: 1000,
|
||||
connectTimeout: 1000,
|
||||
tls: tls
|
||||
});
|
||||
|
||||
// verify connection is using TCP, not UNIX socket
|
||||
assert.strictEqual(client.connection_options.host, 'localhost');
|
||||
assert.strictEqual(client.connection_options.port, tls_port);
|
||||
assert.strictEqual(client.address, 'localhost:' + tls_port);
|
||||
assert.strictEqual(client.connectionOptions.host, 'localhost');
|
||||
assert.strictEqual(client.connectionOptions.port, tlsPort);
|
||||
assert.strictEqual(client.address, 'localhost:' + tlsPort);
|
||||
assert(client.stream.encrypted);
|
||||
|
||||
client.set('foo', 'bar');
|
||||
@@ -110,15 +110,15 @@ describe('TLS connection tests', function () {
|
||||
|
||||
it('fails to connect because the cert is not correct', function (done) {
|
||||
if (skip) this.skip();
|
||||
var faulty_cert = utils.clone(tls_options);
|
||||
faulty_cert.ca = [ String(fs.readFileSync(path.resolve(__dirname, './conf/faulty.cert'))) ];
|
||||
var faultyCert = utils.clone(tlsOptions);
|
||||
faultyCert.ca = [ String(fs.readFileSync(path.resolve(__dirname, './conf/faulty.cert'))) ];
|
||||
client = redis.createClient({
|
||||
host: 'localhost',
|
||||
connect_timeout: 1000,
|
||||
port: tls_port,
|
||||
tls: faulty_cert
|
||||
connectTimeout: 1000,
|
||||
port: tlsPort,
|
||||
tls: faultyCert
|
||||
});
|
||||
assert.strictEqual(client.address, 'localhost:' + tls_port);
|
||||
assert.strictEqual(client.address, 'localhost:' + tlsPort);
|
||||
client.on('error', function (err) {
|
||||
assert(/DEPTH_ZERO_SELF_SIGNED_CERT/.test(err.code || err.message), err);
|
||||
client.end(true);
|
||||
|
@@ -122,9 +122,9 @@ describe('createClient options', function () {
|
||||
});
|
||||
unhookIntercept();
|
||||
assert.strictEqual(text,
|
||||
'node_redis: WARNING: You passed the db option twice!\n' +
|
||||
'node_redis: WARNING: You passed the port option twice!\n' +
|
||||
'node_redis: WARNING: You passed the password option twice!\n'
|
||||
'nodeRedis: WARNING: You passed the db option twice!\n' +
|
||||
'nodeRedis: WARNING: You passed the port option twice!\n' +
|
||||
'nodeRedis: WARNING: You passed the password option twice!\n'
|
||||
);
|
||||
assert.strictEqual(Object.keys(options).length, 5);
|
||||
assert.strictEqual(options.option.length, 3);
|
||||
@@ -162,7 +162,7 @@ describe('createClient options', function () {
|
||||
unhookIntercept();
|
||||
assert.strictEqual(Object.keys(options).length, 1);
|
||||
assert.strictEqual(options.host, 'abc');
|
||||
assert.strictEqual(text, 'node_redis: WARNING: You passed "http" as protocol instead of the "redis" protocol!\n');
|
||||
assert.strictEqual(text, 'nodeRedis: WARNING: You passed "http" as protocol instead of the "redis" protocol!\n');
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -28,25 +28,6 @@ describe('utils.js', function () {
|
||||
assert.strictEqual(Object.keys(b).length, 0);
|
||||
});
|
||||
|
||||
it('transform camelCase options to snake_case and add the camel_case option', function () {
|
||||
var a = utils.clone({
|
||||
optionOneTwo: true,
|
||||
retryStrategy: false,
|
||||
nested: {
|
||||
onlyContainCamelCaseOnce: true
|
||||
},
|
||||
tls: {
|
||||
rejectUnauthorized: true
|
||||
}
|
||||
});
|
||||
assert.strictEqual(Object.keys(a).length, 5);
|
||||
assert.strictEqual(a.option_one_two, true);
|
||||
assert.strictEqual(a.retry_strategy, false);
|
||||
assert.strictEqual(a.camel_case, true);
|
||||
assert.strictEqual(a.tls.rejectUnauthorized, true);
|
||||
assert.strictEqual(Object.keys(a.nested).length, 1);
|
||||
});
|
||||
|
||||
it('throws on circular data', function () {
|
||||
try {
|
||||
var a = {};
|
||||
@@ -59,36 +40,36 @@ describe('utils.js', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('reply_in_order', function () {
|
||||
describe('replyInOrder', function () {
|
||||
|
||||
var err_count = 0;
|
||||
var res_count = 0;
|
||||
var errCount = 0;
|
||||
var resCount = 0;
|
||||
var emitted = false;
|
||||
var clientMock = {
|
||||
emit: function () { emitted = true; },
|
||||
offline_queue: new Queue(),
|
||||
command_queue: new Queue()
|
||||
offlineQueue: new Queue(),
|
||||
commandQueue: new Queue()
|
||||
};
|
||||
var create_command_obj = function () {
|
||||
var createCommandObj = function () {
|
||||
return {
|
||||
callback: function (err, res) {
|
||||
if (err) err_count++;
|
||||
else res_count++;
|
||||
if (err) errCount++;
|
||||
else resCount++;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
clientMock.offline_queue.clear();
|
||||
clientMock.command_queue.clear();
|
||||
err_count = 0;
|
||||
res_count = 0;
|
||||
clientMock.offlineQueue.clear();
|
||||
clientMock.commandQueue.clear();
|
||||
errCount = 0;
|
||||
resCount = 0;
|
||||
emitted = false;
|
||||
});
|
||||
|
||||
it('no elements in either queue. Reply in the next tick with callback', function (done) {
|
||||
var called = false;
|
||||
utils.reply_in_order(clientMock, function () {
|
||||
utils.replyInOrder(clientMock, function () {
|
||||
called = true;
|
||||
done();
|
||||
}, null, null);
|
||||
@@ -97,7 +78,7 @@ describe('utils.js', function () {
|
||||
|
||||
it('no elements in either queue. Reply in the next tick without callback', function (done) {
|
||||
assert(!emitted);
|
||||
utils.reply_in_order(clientMock, null, new Error('tada'));
|
||||
utils.replyInOrder(clientMock, null, new Error('tada'));
|
||||
assert(!emitted);
|
||||
setTimeout(function () {
|
||||
assert(emitted);
|
||||
@@ -105,48 +86,48 @@ describe('utils.js', function () {
|
||||
}, 1);
|
||||
});
|
||||
|
||||
it('elements in the offline queue. Reply after the offline queue is empty and respect the command_obj callback', function (done) {
|
||||
clientMock.offline_queue.push(create_command_obj(), create_command_obj());
|
||||
utils.reply_in_order(clientMock, function () {
|
||||
assert.strictEqual(clientMock.offline_queue.length, 0);
|
||||
assert.strictEqual(res_count, 2);
|
||||
it('elements in the offline queue. Reply after the offline queue is empty and respect the commandObj callback', function (done) {
|
||||
clientMock.offlineQueue.push(createCommandObj(), createCommandObj());
|
||||
utils.replyInOrder(clientMock, function () {
|
||||
assert.strictEqual(clientMock.offlineQueue.length, 0);
|
||||
assert.strictEqual(resCount, 2);
|
||||
done();
|
||||
}, null, null);
|
||||
while (clientMock.offline_queue.length) clientMock.offline_queue.shift().callback(null, 'foo');
|
||||
while (clientMock.offlineQueue.length) clientMock.offlineQueue.shift().callback(null, 'foo');
|
||||
});
|
||||
|
||||
it('elements in the offline queue. Reply after the offline queue is empty and respect the command_obj error emit', function (done) {
|
||||
clientMock.command_queue.push({}, create_command_obj(), {});
|
||||
utils.reply_in_order(clientMock, function () {
|
||||
assert.strictEqual(clientMock.command_queue.length, 0);
|
||||
it('elements in the offline queue. Reply after the offline queue is empty and respect the commandObj error emit', function (done) {
|
||||
clientMock.commandQueue.push({}, createCommandObj(), {});
|
||||
utils.replyInOrder(clientMock, function () {
|
||||
assert.strictEqual(clientMock.commandQueue.length, 0);
|
||||
assert(emitted);
|
||||
assert.strictEqual(err_count, 1);
|
||||
assert.strictEqual(res_count, 0);
|
||||
assert.strictEqual(errCount, 1);
|
||||
assert.strictEqual(resCount, 0);
|
||||
done();
|
||||
}, null, null);
|
||||
while (clientMock.command_queue.length) {
|
||||
var command_obj = clientMock.command_queue.shift();
|
||||
if (command_obj.callback) {
|
||||
command_obj.callback(new Error('tada'));
|
||||
while (clientMock.commandQueue.length) {
|
||||
var commandObj = clientMock.commandQueue.shift();
|
||||
if (commandObj.callback) {
|
||||
commandObj.callback(new Error('tada'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('elements in the offline queue and the command_queue. Reply all other commands got handled respect the command_obj', function (done) {
|
||||
clientMock.command_queue.push(create_command_obj(), create_command_obj());
|
||||
clientMock.offline_queue.push(create_command_obj(), {});
|
||||
utils.reply_in_order(clientMock, function (err, res) {
|
||||
assert.strictEqual(clientMock.command_queue.length, 0);
|
||||
assert.strictEqual(clientMock.offline_queue.length, 0);
|
||||
it('elements in the offline queue and the commandQueue. Reply all other commands got handled respect the commandObj', function (done) {
|
||||
clientMock.commandQueue.push(createCommandObj(), createCommandObj());
|
||||
clientMock.offlineQueue.push(createCommandObj(), {});
|
||||
utils.replyInOrder(clientMock, function (err, res) {
|
||||
assert.strictEqual(clientMock.commandQueue.length, 0);
|
||||
assert.strictEqual(clientMock.offlineQueue.length, 0);
|
||||
assert(!emitted);
|
||||
assert.strictEqual(res_count, 3);
|
||||
assert.strictEqual(resCount, 3);
|
||||
done();
|
||||
}, null, null);
|
||||
while (clientMock.offline_queue.length) {
|
||||
clientMock.command_queue.push(clientMock.offline_queue.shift());
|
||||
while (clientMock.offlineQueue.length) {
|
||||
clientMock.commandQueue.push(clientMock.offlineQueue.shift());
|
||||
}
|
||||
while (clientMock.command_queue.length) {
|
||||
clientMock.command_queue.shift().callback(null, 'hello world');
|
||||
while (clientMock.commandQueue.length) {
|
||||
clientMock.commandQueue.shift().callback(null, 'hello world');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user