Comparing version 0.5.11 to 0.6.0
Changelog | ||
========= | ||
## v0.6.0 - April 21, 2011 | ||
Lots of bugs fixed. | ||
* connection error did not properly trigger reconnection logic [GH-85] | ||
* client.hmget(key, [val1, val2]) was not expanding properly [GH-66] | ||
* client.quit() while in pub/sub mode would throw an error [GH-87] | ||
* client.multi(['hmset', 'key', {foo: 'bar'}]) fails [GH-92] | ||
## v0.5.11 - April 7, 2011 | ||
@@ -5,0 +14,0 @@ |
97
index.js
@@ -6,2 +6,3 @@ /*global Buffer require exports console setTimeout */ | ||
Queue = require("./lib/queue").Queue, | ||
to_array = require("./lib/to_array"), | ||
events = require("events"), | ||
@@ -27,13 +28,2 @@ parsers = [], | ||
function to_array(args) { | ||
var len = args.length, | ||
arr = new Array(len), i; | ||
for (i = 0; i < len; i += 1) { | ||
arr[i] = args[i]; | ||
} | ||
return arr; | ||
} | ||
function RedisClient(stream, options) { | ||
@@ -50,4 +40,5 @@ this.stream = stream; | ||
this.commands_sent = 0; | ||
this.retry_delay = 250; | ||
this.retry_backoff = 1.7; | ||
this.retry_delay = 250; // inital reconnection delay | ||
this.current_retry_delay = this.retry_delay; | ||
this.retry_backoff = 1.7; // each retry waits current delay * retry_backoff | ||
this.subscriptions = false; | ||
@@ -85,3 +76,3 @@ this.monitoring = false; | ||
// "reply error" is an error sent back by redis | ||
// "reply error" is an error sent back by Redis | ||
this.reply_parser.on("reply error", function (reply) { | ||
@@ -110,3 +101,3 @@ self.return_error(new Error(reply)); | ||
} | ||
var message = "Redis connection to " + self.host + ":" + self.port + " failed - " + msg.message; | ||
@@ -130,6 +121,10 @@ | ||
self.command_queue = new Queue(); | ||
self.connected = false; | ||
self.ready = false; | ||
self.emit("error", new Error(message)); | ||
// "error" events get turned into exceptions if they aren't listened for. If the user handled this error | ||
// then we should try to reconnect. | ||
self.connection_gone("error"); | ||
}); | ||
@@ -162,2 +157,3 @@ | ||
this.ready = false; | ||
this.attempts = 0; | ||
this.connections += 1; | ||
@@ -167,3 +163,3 @@ this.command_queue = new Queue(); | ||
this.retry_timer = null; | ||
this.retry_delay = 250; | ||
this.current_retry_delay = this.retry_time; | ||
this.stream.setNoDelay(); | ||
@@ -236,3 +232,3 @@ this.stream.setTimeout(0); | ||
if (!obj["loading"] || (obj["loading"] && obj["loading"] == 0)) { | ||
if (!obj.loading || (obj.loading && obj.loading === "0")) { | ||
if (exports.debug_mode) { | ||
@@ -279,3 +275,3 @@ console.log("Redis server ready."); | ||
// If a retry is already in progress, just let that happen | ||
if (self.retry_timer) { | ||
if (this.retry_timer) { | ||
return; | ||
@@ -285,3 +281,3 @@ } | ||
// Note that this may trigger another "close" or "end" event | ||
self.stream.destroy(); | ||
this.stream.destroy(); | ||
@@ -291,14 +287,14 @@ if (exports.debug_mode) { | ||
} | ||
self.connected = false; | ||
self.ready = false; | ||
self.subscriptions = false; | ||
self.monitoring = false; | ||
this.connected = false; | ||
this.ready = false; | ||
this.subscriptions = false; | ||
this.monitoring = false; | ||
// since we are collapsing end and close, users don't expect to be called twice | ||
if (! self.emitted_end) { | ||
self.emit("end"); | ||
self.emitted_end = true; | ||
if (! this.emitted_end) { | ||
this.emit("end"); | ||
this.emitted_end = true; | ||
} | ||
self.command_queue.forEach(function (args) { | ||
this.command_queue.forEach(function (args) { | ||
if (typeof args[2] === "function") { | ||
@@ -308,26 +304,27 @@ args[2]("Server connection closed"); | ||
}); | ||
self.command_queue = new Queue(); | ||
this.command_queue = new Queue(); | ||
// If this is a requested shutdown, then don't retry | ||
if (self.closing) { | ||
self.retry_timer = null; | ||
if (this.closing) { | ||
this.retry_timer = null; | ||
return; | ||
} | ||
this.current_retry_delay = this.retry_delay * this.retry_backoff; | ||
if (exports.debug_mode) { | ||
console.log("Retry connection in " + self.retry_delay + " ms"); | ||
console.log("Retry connection in " + this.current_retry_delay + " ms"); | ||
} | ||
self.attempts += 1; | ||
self.emit("reconnecting", { | ||
delay: self.retry_delay, | ||
attempt: self.attempts | ||
this.attempts += 1; | ||
this.emit("reconnecting", { | ||
delay: this.current_retry_delay, | ||
attempt: this.attempts | ||
}); | ||
self.retry_timer = setTimeout(function () { | ||
this.retry_timer = setTimeout(function () { | ||
if (exports.debug_mode) { | ||
console.log("Retrying connection..."); | ||
} | ||
self.retry_delay = self.retry_delay * self.retry_backoff; | ||
self.stream.connect(self.port, self.host); | ||
self.retry_timer = null; | ||
}, self.retry_delay); | ||
}, this.current_retry_delay); | ||
}; | ||
@@ -385,3 +382,3 @@ | ||
} | ||
if (command_obj && !command_obj.sub_command) { | ||
@@ -411,3 +408,3 @@ if (typeof command_obj.callback === "function") { | ||
} | ||
} else if (this.subscriptions) { | ||
} else if (this.subscriptions || command_obj.sub_command) { | ||
if (Array.isArray(reply)) { | ||
@@ -431,3 +428,3 @@ type = reply[0].toString(); | ||
} | ||
} else { | ||
} else if (! this.closing) { | ||
throw new Error("subscriptions are active but got an invalid reply: " + reply); | ||
@@ -476,2 +473,6 @@ } | ||
if (args.length === 2 && Array.isArray(args[1])) { | ||
args = [args[0]].concat(args[1]); | ||
} | ||
command_obj = { | ||
@@ -593,3 +594,4 @@ command: command, | ||
// list commands | ||
"rpush", "lpush", "rpushx", "lpushx", "linsert", "rpop", "lpop", "brpop", "blpop", "llen", "lindex", "lset", "lrange", "ltrim", "lrem", "rpoplpush", | ||
"rpush", "lpush", "rpushx", "lpushx", "linsert", "rpop", "lpop", "brpop", "blpop", "brpoplpush", "llen", "lindex", "lset", "lrange", | ||
"ltrim", "lrem", "rpoplpush", | ||
// set commands | ||
@@ -689,3 +691,3 @@ "sadd", "srem", "smove", "sismember", "scard", "spop", "srandmember", "sinter", "sinterstore", "sunion", "sunionstore", "sdiff", "sdiffstore", "smembers", | ||
this.queue.forEach(function (args, index) { | ||
var command = args[0]; | ||
var command = args[0], obj; | ||
if (typeof args[args.length - 1] === "function") { | ||
@@ -699,2 +701,9 @@ args = args.slice(1, -1); | ||
} | ||
if (command === 'hmset' && typeof args[1] === 'object') { | ||
obj = args.pop(); | ||
Object.keys(obj).forEach(function (key) { | ||
args.push(key); | ||
args.push(obj[key]); | ||
}); | ||
} | ||
this.client.send_command(command, args, function (err, reply) { | ||
@@ -701,0 +710,0 @@ if (err) { |
@@ -1,20 +0,11 @@ | ||
function to_array(args) { | ||
var len = args.length, | ||
arr = new Array(len), i; | ||
var to_array = require("./to_array"); | ||
for (i = 0; i < len; i += 1) { | ||
arr[i] = args[i]; | ||
} | ||
return arr; | ||
} | ||
// Queue class adapted from Tim Caswell's pattern library | ||
// http://github.com/creationix/pattern/blob/master/lib/pattern/queue.js | ||
var Queue = function () { | ||
function Queue() { | ||
this.tail = []; | ||
this.head = to_array(arguments); | ||
this.offset = 0; | ||
}; | ||
} | ||
@@ -21,0 +12,0 @@ Queue.prototype.shift = function () { |
{ "name" : "redis", | ||
"version" : "0.5.11", | ||
"version" : "0.6.0", | ||
"description" : "Redis client library", | ||
@@ -14,3 +14,4 @@ "author": "Matt Ranney <mjr@ranney.com>", | ||
"Pieter Noordhuis", | ||
"Andy Ray" | ||
"Andy Ray", | ||
"Vladimir Dronnikov" | ||
], | ||
@@ -17,0 +18,0 @@ "main": "./index.js", |
@@ -540,2 +540,3 @@ redis - a node.js redis client | ||
* [Pieter Noordhuis](https://github.com/pietern) | ||
* [Vladimir Dronnikov](https://github.com/dvv) | ||
@@ -542,0 +543,0 @@ Thanks. |
11
test.js
@@ -321,3 +321,12 @@ /*global require console setTimeout process Buffer */ | ||
}); | ||
client.HMGET(key1, ["0123456789"], function (err, reply) { | ||
assert.strictEqual("abcdefghij", reply[0], name); | ||
}); | ||
client.HMGET(key1, ["0123456789", "some manner of key"], function (err, reply) { | ||
assert.strictEqual("abcdefghij", reply[0], name); | ||
assert.strictEqual("a type of value", reply[1], name); | ||
}); | ||
client.HMGET(key1, "missing thing", "another missing thing", function (err, reply) { | ||
@@ -324,0 +333,0 @@ assert.strictEqual(null, reply[0], name); |
119425
29
2476
570