From 83dc4c999b7b00c529d254f0acd0881d48052b7d Mon Sep 17 00:00:00 2001 From: Shankar Karuppiah Date: Tue, 8 May 2012 13:00:12 +0300 Subject: [PATCH] Added option to disable offline queue Signed-off-by: DTrejo --- index.js | 23 ++++++++++++----- test.js | 78 +++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 76 insertions(+), 25 deletions(-) diff --git a/index.js b/index.js index 22e3b553a4..b3f0beda57 100644 --- a/index.js +++ b/index.js @@ -50,6 +50,8 @@ function RedisClient(stream, options) { if (options.connect_timeout && !isNaN(options.connect_timeout) && options.connect_timeout > 0) { this.connect_timeout = +options.connect_timeout; } + this.enable_offline_queue = this.options.enable_offline_queue || true; + this.initialize_retry_vars(); this.pub_sub_mode = false; this.subscription_set = {}; @@ -59,7 +61,7 @@ function RedisClient(stream, options) { this.auth_pass = null; this.parser_module = null; this.selected_db = null; // save the selected db here, used when reconnecting - + var self = this; this.stream.on("connect", function () { @@ -661,11 +663,18 @@ RedisClient.prototype.send_command = function (command, args, callback) { if (!stream.writable) { console.log("send command: stream is not writeable."); } - - console.log("Queueing " + command + " for next server connection."); } - this.offline_queue.push(command_obj); - this.should_buffer = true; + + if (this.enable_offline_queue) { + if (exports.debug_mode) { + console.log("Queueing " + command + " for next server connection."); + } + this.offline_queue.push(command_obj); + this.should_buffer = true; + } else { + command_obj.callback(new Error('send command: stream is not writeable.')); + } + return false; } @@ -745,7 +754,7 @@ RedisClient.prototype.send_command = function (command, args, callback) { RedisClient.prototype.pub_sub_command = function (command_obj) { var i, key, command, args; - + if (this.pub_sub_mode === false && exports.debug_mode) { console.log("Entering pub/sub mode from " + command_obj.command); } @@ -795,7 +804,7 @@ exports.Multi = Multi; // take 2 arrays and return the union of their elements function set_union(seta, setb) { var obj = {}; - + seta.forEach(function (val) { obj[val] = true; }); diff --git a/test.js b/test.js index 0fa15e9a79..222abad37d 100644 --- a/test.js +++ b/test.js @@ -645,7 +645,7 @@ tests.TYPE = function () { client.sadd(["set key", "should be a set"], require_number_any(name)); client.zadd(["zset key", "10.0", "should be a zset"], require_number_any(name)); client.hset(["hash key", "hashtest", "should be a hash"], require_number_any(0, name)); - + client.TYPE(["string key"], require_string("string", name)); client.TYPE(["list key"], require_string("list", name)); client.TYPE(["set key"], require_string("set", name)); @@ -825,7 +825,7 @@ tests.UTF8 = function () { tests.SADD = function () { var name = "SADD"; - + client.del('set0'); client.sadd('set0', 'member0', require_number(1, name)); client.sadd('set0', 'member0', last(name, require_number(0, name))); @@ -833,7 +833,7 @@ tests.SADD = function () { tests.SADD2 = function () { var name = "SADD2"; - + client.del("set0"); client.sadd("set0", ["member0", "member1", "member2"], require_number(3, name)); client.smembers("set0", function (err, res) { @@ -847,7 +847,7 @@ tests.SADD2 = function () { tests.SISMEMBER = function () { var name = "SISMEMBER"; - + client.del('set0'); client.sadd('set0', 'member0', require_number(1, name)); client.sismember('set0', 'member0', require_number(1, name)); @@ -856,7 +856,7 @@ tests.SISMEMBER = function () { tests.SCARD = function () { var name = "SCARD"; - + client.del('set0'); client.sadd('set0', 'member0', require_number(1, name)); client.scard('set0', require_number(1, name)); @@ -876,7 +876,7 @@ tests.SREM = function () { tests.SPOP = function () { var name = "SPOP"; - + client.del('zzz'); client.sadd('zzz', 'member0', require_number(1, name)); client.scard('zzz', require_number(1, name)); @@ -893,7 +893,7 @@ tests.SPOP = function () { tests.SDIFF = function () { var name = "SDIFF"; - + client.del('foo'); client.sadd('foo', 'x', require_number(1, name)); client.sadd('foo', 'a', require_number(1, name)); @@ -919,7 +919,7 @@ tests.SDIFF = function () { tests.SDIFFSTORE = function () { var name = "SDIFFSTORE"; - + client.del('foo'); client.del('bar'); client.del('baz'); @@ -952,7 +952,7 @@ tests.SDIFFSTORE = function () { tests.SMEMBERS = function () { var name = "SMEMBERS"; - + client.del('foo'); client.sadd('foo', 'x', require_number(1, name)); @@ -996,7 +996,7 @@ tests.SINTER = function () { client.del('sa'); client.del('sb'); client.del('sc'); - + client.sadd('sa', 'a', require_number(1, name)); client.sadd('sa', 'b', require_number(1, name)); client.sadd('sa', 'c', require_number(1, name)); @@ -1078,11 +1078,11 @@ tests.SINTERSTORE = function () { tests.SUNION = function () { var name = "SUNION"; - + client.del('sa'); client.del('sb'); client.del('sc'); - + client.sadd('sa', 'a', require_number(1, name)); client.sadd('sa', 'b', require_number(1, name)); client.sadd('sa', 'c', require_number(1, name)); @@ -1106,12 +1106,12 @@ tests.SUNION = function () { tests.SUNIONSTORE = function () { var name = "SUNIONSTORE"; - + client.del('sa'); client.del('sb'); client.del('sc'); client.del('foo'); - + client.sadd('sa', 'a', require_number(1, name)); client.sadd('sa', 'b', require_number(1, name)); client.sadd('sa', 'c', require_number(1, name)); @@ -1148,7 +1148,7 @@ tests.SORT = function () { client.del('y'); client.del('x'); - + client.rpush('y', 'd', require_number(1, name)); client.rpush('y', 'b', require_number(2, name)); client.rpush('y', 'a', require_number(3, name)); @@ -1257,7 +1257,7 @@ tests.SORT = function () { assert.deepEqual(buffers_to_strings(values), ['foo', 'bux', 'bar', 'tux', 'baz', 'lux', 'buz', 'qux'], name); next(name); }); - + // TODO - sort by hash value }; @@ -1302,7 +1302,7 @@ tests.BLPOP = function () { client2.BLPOP("blocking list", 0, function (err, res) { assert.strictEqual("blocking list", res[0].toString()); assert.strictEqual("initial value", res[1].toString()); - + client.rpush("blocking list", "wait for this value"); }); client2.BLPOP("blocking list", 0, function (err, res) { @@ -1315,7 +1315,7 @@ tests.BLPOP = function () { tests.BLPOP_TIMEOUT = function () { var name = "BLPOP_TIMEOUT"; - + // try to BLPOP the list again, which should be empty. This should timeout and return null. client2.BLPOP("blocking list", 1, function (err, res) { if (err) { @@ -1377,6 +1377,48 @@ tests.HMSET_THROWS_ON_NON_STRINGS = function () { next(name); }; +tests.ENABLE_OFFLINE_QUEUE_TRUE = function () { + var name = "ENABLE_OFFLINE_QUEUE_TRUE"; + var cli = redis.createClient(9999, null, { + max_attempts: 1 + // default :) + // enable_offline_queue: true + }); + cli.on('error', function(e) { + // ignore, b/c expecting a "can't connect" error + }); + return setTimeout(function() { + cli.set(name, name, function(err, result) { + assert.ifError(err); + }); + + return setTimeout(function(){ + assert.strictEqual(cli.offline_queue.length, 1); + return next(name); + }, 25); + }, 50); +}; + +tests.ENABLE_OFFLINE_QUEUE_FALSE = function () { + var name = "ENABLE_OFFLINE_QUEUE_FALSE"; + var cli = redis.createClient(9999, null, { + max_attempts: 1, + enable_offline_queue: false + }); + cli.on('error', function() { + // ignore, see above + }); + assert.throws(function () { + cli.set(name, name) + }) + assert.doesNotThrow(function () { + cli.set(name, name, function (err) { + // should callback with an error + assert.ok(err); + }); + }); +}; + // TODO - need a better way to test auth, maybe auto-config a local Redis server or something. // Yes, this is the real password. Please be nice, thanks. tests.auth = function () {