From 11db346e733db5b7de8d8a44f1b45bfaf1cd75e8 Mon Sep 17 00:00:00 2001 From: roam Date: Wed, 19 Dec 2012 15:04:07 +0800 Subject: [PATCH 1/3] Fixed an unexpected exception bug when reconnecting in pub/sub mode if selected_db is not null RedisClient might enter pub/sub mode after at least one SELECT command issued. When reconnecting, the SELECT command is issued after restoring pub_sub_command to true, which causes an exception. --- index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/index.js b/index.js index 2dc86a9659..2c2ae23c7f 100644 --- a/index.js +++ b/index.js @@ -282,7 +282,12 @@ RedisClient.prototype.on_ready = function () { // magically restore any modal commands from a previous connection if (this.selected_db !== null) { + // this trick works if and only if the following send_command + // never goes into the offline queue + var pub_sub_mode = this.pub_sub_mode; + this.pub_sub_mode = false; this.send_command('select', [this.selected_db]); + this.pub_sub_mode = pub_sub_mode; } if (this.pub_sub_mode === true) { // only emit "ready" when all subscriptions were made again From 6fb7204ca5bb0b101bb70cdcc5dadae566ff2808 Mon Sep 17 00:00:00 2001 From: roam Date: Mon, 18 Mar 2013 16:08:58 +0800 Subject: [PATCH 2/3] Add a test case for reconnect_select_db_after_pubsub --- test.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test.js b/test.js index 94bd19d682..13a53d7c6c 100644 --- a/test.js +++ b/test.js @@ -516,6 +516,27 @@ tests.reconnect = function () { }); }; +tests.reconnect_select_db_after_pubsub = function() { + var name = "reconnect_select_db_after_pubsub"; + + client.select(test_db_num); + client.set(name, "one"); + client.subscribe('ChannelV', function (err, res) { + client.stream.destroy(); + }); + + client.on("reconnecting", function on_recon(params) { + client.on("ready", function on_connect() { + client.unsubscribe('ChannelV', function (err, res) { + client.get(name, require_string("one", name)); + client.removeListener("connect", on_connect); + client.removeListener("reconnecting", on_recon); + next(name); + }); + }); + }); +}; + tests.idle = function () { var name = "idle"; From 290de97e18d8a0717f8d223e57d342a9c8244970 Mon Sep 17 00:00:00 2001 From: roam Date: Mon, 18 Mar 2013 16:27:55 +0800 Subject: [PATCH 3/3] Fixed a subtle error where commands issued within the idle event handler --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 2c2ae23c7f..028b38866b 100644 --- a/index.js +++ b/index.js @@ -492,8 +492,8 @@ RedisClient.prototype.return_error = function (err) { var command_obj = this.command_queue.shift(), queue_len = this.command_queue.getLength(); if (this.pub_sub_mode === false && queue_len === 0) { - this.emit("idle"); this.command_queue = new Queue(); + this.emit("idle"); } if (this.should_buffer && queue_len <= this.command_queue_low_water) { this.emit("drain"); @@ -571,8 +571,8 @@ RedisClient.prototype.return_reply = function (reply) { queue_len = this.command_queue.getLength(); if (this.pub_sub_mode === false && queue_len === 0) { - this.emit("idle"); this.command_queue = new Queue(); // explicitly reclaim storage from old Queue + this.emit("idle"); } if (this.should_buffer && queue_len <= this.command_queue_low_water) { this.emit("drain");