Skip to content
This repository
Browse code

Support for multiple reply parsers including hiredis.

Several parsing bugs fixed in JavaScript.
Some new config options that need to be better documented.
  • Loading branch information...
commit b9073645735cb3415f8056a42951ad22655832b1 1 parent 232f34a
Matt Ranney authored
35 README.md
Source Rendered
... ... @@ -1,22 +1,26 @@
1 1 redis - a node.js redis client
2 2 ===========================
3 3
4   -This is a complete Redis client for node.js. It is designed for node 0.2.2+ and redis 2.0.1+.
5   -It might not work on earlier versions of either, although it probably will.
6   -
7   -This client supports all Redis commands, including MULTI and PUBLISH/SUBSCRIBE.
  4 +This is a complete Redis client for node.js. It supports all Redis commands, including MULTI, WATCH, and PUBLISH/SUBSCRIBE.
8 5
9 6 Install with:
10 7
11 8 npm install redis
  9 +
  10 +By default, a pure JavaScript reply parser is used. This is clever and portable, but not as fast for large responses as `hiredis` from the
  11 +Redis distribution. To use the `hiredis`, do:
  12 +
  13 + npm install hiredis
  14 +
  15 +If `hiredis` is installed, `node_redis` will use it by default.
12 16
13 17 ## Why?
14 18
15   -`node_redis` works in the latest versions of node, is published in `npm`, and is very fast, particularly for small responses.
  19 +`node_redis` works in the latest versions of node, is published in `npm`, is used by many people, and is in production on a
  20 +number of sites.
16 21
17   -`node_redis` is designed with performance in mind. The included `bench.js` runs similar tests to `redis-benchmark`, included with the Redis
18   -distribution, and `bench.js` is as fast as `redis-benchmark` for some patterns and slower for others. `node_redis` has many lovingly
19   -hand-crafted optimizations for speed.
  22 +`node_redis` was originally written to replace `node-redis-client` which hasn't been updated in a while, and no longer works
  23 +on recent versions of node.
20 24
21 25
22 26 ## Usage
@@ -27,7 +31,7 @@ Simple example, included as `example.js`:
27 31 client = redis.createClient();
28 32
29 33 client.on("error", function (err) {
30   - console.log("Redis connection error to " + client.host + ":" + client.port + " - " + err);
  34 + console.log("Error " + err);
31 35 });
32 36
33 37 client.set("string key", "string val", redis.print);
@@ -392,22 +396,12 @@ Defaults to 1.7. The default initial connection retry is 250, so the second ret
392 396
393 397 ## TODO
394 398
395   -Many common uses of Redis are fine with JavaScript Strings, and Strings are faster than Buffers. We should get a way to
396   -use Strings if binary-safety isn't a concern. Also, dealing with Buffer results is kind of annoying.
397   -
398   -Stream large set/get into and out of Redis.
  399 +Stream large set/get values into and out of Redis. Otherwise the entire value must be in node's memory.
399 400
400 401 Performance can be better for very large values.
401 402
402 403 I think there are more performance improvements left in there for smaller values, especially for large lists of small values.
403 404
404   -## Also
405   -
406   -This library might still have some bugs in it, but it seems to be quite useful for a lot of people at this point.
407   -There are other Redis libraries available for node, and they might work better for you.
408   -
409   -Comments and patches welcome.
410   -
411 405 ## Contributors
412 406
413 407 Some people have have added features and fixed bugs in `node_redis` other than me.
@@ -421,6 +415,7 @@ In order of first contribution, they are:
421 415 * [Hank Sims](http://github.com/hanksims)
422 416 * [Aivo Paas](http://github.com/aivopaas)
423 417 * [Paul Carey](https://github.com/paulcarey)
  418 +* [Pieter Noordhuis](https://github.com/pietern)
424 419
425 420 Thanks.
426 421
5 changelog.md
Source Rendered
... ... @@ -1,6 +1,11 @@
1 1 Changelog
2 2 =========
3 3
  4 +## v0.4.0 - December 5, 2010
  5 +
  6 +Support for multiple response parsers and hiredis.
  7 +Return Strings instead of Buffers by default.
  8 +
4 9 ## v0.3.9 - November 30, 2010
5 10
6 11 Fix parser bug on failed EXECs.
24 examples/unix_socket.js
... ... @@ -1,5 +1,6 @@
1 1 var redis = require("redis"),
2   - client = redis.createClient("/tmp/redis.sock");
  2 + client = redis.createClient("/tmp/redis.sock"),
  3 + profiler = require("v8-profiler");
3 4
4 5 client.on("connect", function () {
5 6 console.log("Got Unix socket connection.")
@@ -9,7 +10,20 @@ client.on("error", function (err) {
9 10 console.log(err.message);
10 11 });
11 12
12   -client.info(function (err, reply) {
13   - console.log(reply.toString());
14   - client.quit();
15   -});
  13 +client.set("space chars", "space value");
  14 +
  15 +setInterval(function () {
  16 + client.get("space chars");
  17 +}, 100);
  18 +
  19 +function done() {
  20 + client.info(function (err, reply) {
  21 + console.log(reply.toString());
  22 + client.quit();
  23 + });
  24 +}
  25 +
  26 +setTimeout(function () {
  27 + console.log("Taking snapshot.");
  28 + var snap = profiler.takeSnapshot();
  29 +}, 5000);
105 index.js
@@ -2,22 +2,23 @@
2 2
3 3 var net = require("net"),
4 4 util = require("./lib/util").util,
  5 + Queue = require("./lib/queue").Queue,
5 6 events = require("events"),
6   - reply_parser,
  7 + parsers = [],
7 8 default_port = 6379,
8 9 default_host = "127.0.0.1";
9 10
10   -// Try to use hiredis for reply parsing and fall back on the Javascript-based
11   -// reply parsing code when its not available.
  11 +// hiredis might not be installed
12 12 try {
13   - if (process.env["DISABLE_HIREDIS"])
14   - throw new Error(); // Fall back to the Javascript reply parsing code
15   - reply_parser = require("./lib/parser/hiredis");
16   -} catch(err) {
17   - reply_parser = require("./lib/parser/javascript");
  13 + require("./lib/parser/hiredis");
  14 + parsers.push(require("./lib/parser/hiredis"));
  15 +} catch (err) {
  16 + console.log("hiredis parser not installed.");
18 17 }
19 18
20   -// can can set this to true to enable for all connections
  19 +parsers.push(require("./lib/parser/javascript"));
  20 +
  21 +// can set this to true to enable for all connections
21 22 exports.debug_mode = false;
22 23
23 24 function to_array(args) {
@@ -31,62 +32,12 @@ function to_array(args) {
31 32 return arr;
32 33 }
33 34
34   -// Queue class adapted from Tim Caswell's pattern library
35   -// http://github.com/creationix/pattern/blob/master/lib/pattern/queue.js
36   -var Queue = function () {
37   - this.tail = [];
38   - this.head = to_array(arguments);
39   - this.offset = 0;
40   -};
41   -
42   -Queue.prototype.shift = function () {
43   - if (this.offset === this.head.length) {
44   - var tmp = this.head;
45   - tmp.length = 0;
46   - this.head = this.tail;
47   - this.tail = tmp;
48   - this.offset = 0;
49   - if (this.head.length === 0) {
50   - return;
51   - }
52   - }
53   - return this.head[this.offset++]; // sorry, JSLint
54   -};
55   -
56   -Queue.prototype.push = function (item) {
57   - return this.tail.push(item);
58   -};
59   -
60   -Queue.prototype.forEach = function (fn, thisv) {
61   - var array = this.head.slice(this.offset), i, il;
62   -
63   - array.push.apply(array, this.tail);
64   -
65   - if (thisv) {
66   - for (i = 0, il = array.length; i < il; i += 1) {
67   - fn.call(thisv, array[i], i, array);
68   - }
69   - } else {
70   - for (i = 0, il = array.length; i < il; i += 1) {
71   - fn(array[i], i, array);
72   - }
73   - }
74   -
75   - return array;
76   -};
77   -
78   -Object.defineProperty(Queue.prototype, 'length', {
79   - get: function () {
80   - return this.head.length - this.offset + this.tail.length;
81   - }
82   -});
83   -
84 35 function RedisClient(stream, options) {
85 36 events.EventEmitter.call(this);
86 37
87 38 this.stream = stream;
88   - this.options = options;
89   -
  39 + this.options = options || {};
  40 +
90 41 this.connected = false;
91 42 this.connections = 0;
92 43 this.attempts = 1;
@@ -98,7 +49,31 @@ function RedisClient(stream, options) {
98 49 this.subscriptions = false;
99 50 this.closing = false;
100 51
101   - var self = this;
  52 + var parser_module, self = this;
  53 +
  54 + if (self.options.parser) {
  55 + if (! parsers.some(function (parser) {
  56 + if (parser.name === self.options.parser) {
  57 + parser_module = parser;
  58 + if (exports.debug_mode) {
  59 + console.log("Using parser module: " + parser_module.name);
  60 + }
  61 + return true;
  62 + }
  63 + })) {
  64 + throw new Error("Couldn't find named parser " + self.options.parser + " on this system");
  65 + }
  66 + } else {
  67 + if (exports.debug_mode) {
  68 + console.log("Using default parser module: " + parsers[0].name);
  69 + }
  70 + parser_module = parsers[0];
  71 + }
  72 +
  73 + parser_module.debug_mode = exports.debug_mode;
  74 + this.reply_parser = new parser_module.Parser({
  75 + return_buffers: self.options.return_buffers || false
  76 + });
102 77
103 78 this.stream.on("connect", function () {
104 79 if (exports.debug_mode) {
@@ -109,8 +84,6 @@ function RedisClient(stream, options) {
109 84 self.command_queue = new Queue();
110 85 self.emitted_end = false;
111 86
112   - reply_parser.debug_mode = exports.debug_mode;
113   - self.reply_parser = new reply_parser.Parser({ return_buffers: false });
114 87 // "reply error" is an error sent back by redis
115 88 self.reply_parser.on("reply error", function (reply) {
116 89 self.return_error(reply);
@@ -379,7 +352,7 @@ RedisClient.prototype.send_command = function () {
379 352 });
380 353
381 354 // Always use "Multi bulk commands", but if passed any Buffer args, then do multiple writes, one for each arg
382   - // This means that using Buffers in commands is going to be slower, so use Strings if you don't need binary.
  355 + // This means that using Buffers in commands is going to be slower, so use Strings if you don't already have a Buffer.
383 356
384 357 command_str = "*" + elem_count + "\r\n$" + command.length + "\r\n" + command + "\r\n";
385 358
@@ -563,7 +536,7 @@ exports.createClient = function (port_arg, host_arg, options) {
563 536 red_client, net_client;
564 537
565 538 net_client = net.createConnection(port, host);
566   -
  539 +
567 540 red_client = new RedisClient(net_client, options);
568 541
569 542 red_client.port = port;
27 lib/parser/hiredis.js
... ... @@ -1,11 +1,15 @@
  1 +/*global Buffer require exports console setTimeout */
  2 +
1 3 var events = require("events"),
2 4 util = require("../util").util,
3 5 hiredis = require("hiredis");
4 6
  7 +exports.debug_mode = false;
  8 +exports.name = "hiredis";
  9 +
5 10 function HiredisReplyParser(options) {
  11 + this.name = exports.name;
6 12 this.options = options || {};
7   - this.return_buffers = this.options.return_buffers;
8   - if (this.return_buffers == undefined) this.return_buffers = true;
9 13 this.reset();
10 14 events.EventEmitter.call(this);
11 15 }
@@ -13,26 +17,25 @@ function HiredisReplyParser(options) {
13 17 util.inherits(HiredisReplyParser, events.EventEmitter);
14 18
15 19 exports.Parser = HiredisReplyParser;
16   -exports.debug_mode = false;
17   -exports.type = "hiredis";
18 20
19   -HiredisReplyParser.prototype.reset = function() {
20   - this.reader = new hiredis.Reader({ return_buffers: this.return_buffers });
21   -}
  21 +HiredisReplyParser.prototype.reset = function () {
  22 + this.reader = new hiredis.Reader({
  23 + return_buffers: this.options.return_buffers || false
  24 + });
  25 +};
22 26
23   -HiredisReplyParser.prototype.execute = function(data) {
  27 +HiredisReplyParser.prototype.execute = function (data) {
24 28 var reply;
25 29 this.reader.feed(data);
26 30 try {
27 31 while ((reply = this.reader.get()) !== undefined) {
28   - if (reply && reply.constructor == Error) {
  32 + if (reply && reply.constructor === Error) {
29 33 this.emit("reply error", reply);
30 34 } else {
31 35 this.emit("reply", reply);
32 36 }
33 37 }
34   - } catch(err) {
  38 + } catch (err) {
35 39 this.emit("error", err);
36 40 }
37   -}
38   -
  41 +};
55 lib/parser/javascript.js
... ... @@ -1,10 +1,14 @@
  1 +/*global Buffer require exports console setTimeout */
  2 +
1 3 var events = require("events"),
2 4 util = require("../util").util;
3 5
  6 +exports.debug_mode = false;
  7 +exports.name = "javascript";
  8 +
4 9 function RedisReplyParser(options) {
  10 + this.name = exports.name;
5 11 this.options = options || {};
6   - this.return_buffers = this.options.return_buffers;
7   - if (this.return_buffers == undefined) this.return_buffers = true;
8 12 this.reset();
9 13 events.EventEmitter.call(this);
10 14 }
@@ -12,8 +16,6 @@ function RedisReplyParser(options) {
12 16 util.inherits(RedisReplyParser, events.EventEmitter);
13 17
14 18 exports.Parser = RedisReplyParser;
15   -exports.debug_mode = false;
16   -exports.type = "javascript";
17 19
18 20 // Buffer.toString() is quite slow for small strings
19 21 function small_toString(buf) {
@@ -39,13 +41,18 @@ RedisReplyParser.prototype.reset = function () {
39 41 this.multi_bulk_nested_replies = null;
40 42 };
41 43
  44 +RedisReplyParser.prototype.parser_error = function (message) {
  45 + this.emit("error", message);
  46 + this.reset();
  47 +};
  48 +
42 49 RedisReplyParser.prototype.execute = function (incoming_buf) {
43 50 var pos = 0, bd_tmp, bd_str, i, il;
44 51 //, state_times = {}, start_execute = new Date(), start_switch, end_switch, old_state;
45 52 //start_switch = new Date();
46 53
47 54 while (pos < incoming_buf.length) {
48   - // old_state = this.state;
  55 + // old_state = this.state;
49 56 // console.log("execute: " + this.state + ", " + pos + "/" + incoming_buf.length + ", " + String.fromCharCode(incoming_buf[pos]));
50 57
51 58 switch (this.state) {
@@ -137,11 +144,11 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
137 144 this.send_reply(null);
138 145 this.multi_bulk_length = 0;
139 146 } else if (this.multi_bulk_length === 0) {
  147 + this.multi_bulk_replies = null;
140 148 this.send_reply([]);
141 149 }
142 150 } else {
143   - this.emit("error", new Error("didn't see LF after NL reading multi bulk count"));
144   - this.reset();
  151 + this.parser_error(new Error("didn't see LF after NL reading multi bulk count"));
145 152 return;
146 153 }
147 154 pos += 1;
@@ -171,13 +178,11 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
171 178 console.log("Growing return_buffer from " + this.return_buffer.length + " to " + this.bulk_length);
172 179 }
173 180 this.return_buffer = new Buffer(this.bulk_length);
174   - // home the old one gets cleaned up somehow
175 181 }
176 182 this.return_buffer.end = 0;
177 183 }
178 184 } else {
179   - this.emit("error", new Error("didn't see LF after NL while reading bulk length"));
180   - this.reset();
  185 + this.parser_error(new Error("didn't see LF after NL while reading bulk length"));
181 186 return;
182 187 }
183 188 pos += 1;
@@ -186,10 +191,9 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
186 191 this.return_buffer[this.return_buffer.end] = incoming_buf[pos];
187 192 this.return_buffer.end += 1;
188 193 pos += 1;
189   - // TODO - should be faster to use Bufer.copy() here, especially if the response is large.
190   - // However, when the response is small, Buffer.copy() seems a lot slower. Computers are hard.
191 194 if (this.return_buffer.end === this.bulk_length) {
192 195 bd_tmp = new Buffer(this.bulk_length);
  196 + // When the response is small, Buffer.copy() is a lot slower.
193 197 if (this.bulk_length > 10) {
194 198 this.return_buffer.copy(bd_tmp, 0, 0, this.bulk_length);
195 199 } else {
@@ -206,8 +210,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
206 210 this.state = "final lf";
207 211 pos += 1;
208 212 } else {
209   - this.emit("error", new Error("saw " + incoming_buf[pos] + " when expecting final CR"));
210   - this.reset();
  213 + this.parser_error(new Error("saw " + incoming_buf[pos] + " when expecting final CR"));
211 214 return;
212 215 }
213 216 break;
@@ -216,13 +219,12 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
216 219 this.state = "type";
217 220 pos += 1;
218 221 } else {
219   - this.emit("error", new Error("saw " + incoming_buf[pos] + " when expecting final LF"));
220   - this.reset();
  222 + this.parser_error(new Error("saw " + incoming_buf[pos] + " when expecting final LF"));
221 223 return;
222 224 }
223 225 break;
224 226 default:
225   - throw new Error("invalid state " + this.state);
  227 + this.parser_error(new Error("invalid state " + this.state));
226 228 }
227 229 // end_switch = new Date();
228 230 // if (state_times[old_state] === undefined) {
@@ -248,14 +250,23 @@ RedisReplyParser.prototype.send_error = function (reply) {
248 250
249 251 RedisReplyParser.prototype.send_reply = function (reply) {
250 252 if (this.multi_bulk_length > 0 || this.multi_bulk_nested_length > 0) {
251   - if (!this.return_buffers && Buffer.isBuffer(reply)) {
252   - this.add_multi_bulk_reply(reply.toString("utf8"));
  253 + if (!this.options.return_buffers && Buffer.isBuffer(reply)) {
  254 + if (reply.end > 10) {
  255 + this.add_multi_bulk_reply(reply.toString());
  256 + } else {
  257 + this.add_multi_bulk_reply(small_toString(reply));
  258 + }
253 259 } else {
254 260 this.add_multi_bulk_reply(reply);
255 261 }
256 262 } else {
257   - if (!this.return_buffers && Buffer.isBuffer(reply)) {
258   - this.emit("reply", reply.toString("utf8"));
  263 + if (!this.options.return_buffers && Buffer.isBuffer(reply)) {
  264 + console.log("converting buffer to string of len " + reply.end + ", " + util.inspect(reply));
  265 + if (reply.length > 10) {
  266 + this.emit("reply", reply.toString());
  267 + } else {
  268 + this.emit("reply", small_toString(reply));
  269 + }
259 270 } else {
260 271 this.emit("reply", reply);
261 272 }
@@ -265,7 +276,6 @@ RedisReplyParser.prototype.send_reply = function (reply) {
265 276 RedisReplyParser.prototype.add_multi_bulk_reply = function (reply) {
266 277 if (this.multi_bulk_replies) {
267 278 this.multi_bulk_replies.push(reply);
268   - // use "less than" here because a nil mb reply claims "0 length", but we need 1 slot to hold it
269 279 if (this.multi_bulk_replies.length < this.multi_bulk_length) {
270 280 return;
271 281 }
@@ -288,4 +298,3 @@ RedisReplyParser.prototype.add_multi_bulk_reply = function (reply) {
288 298 this.multi_bulk_replies = null;
289 299 }
290 300 };
291   -
3  lib/util.js
... ... @@ -1,7 +1,6 @@
1 1 if (process.versions.node.match(/^0.3/)) {
2 2 exports.util = require("util");
3 3 } else {
4   - /* This module is called "sys" in 0.2.x */
  4 + // This module is called "sys" in 0.2.x
5 5 exports.util = require("sys");
6 6 }
7   -
38 multi_bench.js
@@ -46,19 +46,26 @@ tests.push({
46 46 });
47 47
48 48 function create_clients(callback) {
49   - if (active_clients == num_clients) {
  49 + if (active_clients === num_clients) {
  50 + // common case is all clients are already created
  51 + console.log("create_clients: all clients already created " + num_clients);
50 52 callback();
51 53 } else {
52   - var client;
53   - var connected = active_clients;
  54 + var client, connected = active_clients;
54 55
55 56 while (active_clients < num_clients) {
56   - client = clients[active_clients++] = redis.createClient();
  57 + client = clients[active_clients++] = redis.createClient(6379, "127.0.0.1", {
  58 + parser: "hiredis",
  59 + return_buffers: false
  60 + });
57 61 client.on("connect", function() {
58   - /* Fire callback when all clients are connected */
59   - if (++connected == num_clients)
  62 + // Fire callback when all clients are connected
  63 + connected += 1;
  64 + if (connected === num_clients) {
60 65 callback();
  66 + }
61 67 });
  68 + // TODO - need to check for client disconnect
62 69 client.on("error", function (msg) {
63 70 console.log("Connect problem:" + msg.stack);
64 71 });
@@ -68,10 +75,10 @@ function create_clients(callback) {
68 75
69 76 function issue_request(client, test, cmd, args) {
70 77 var i = issued_requests++;
71   - latency[i] = new Date;
  78 + latency[i] = Date.now();
72 79
73 80 client[cmd](args, function() {
74   - latency[i] = (new Date) - latency[i];
  81 + latency[i] = Date.now() - latency[i];
75 82 if (issued_requests < num_requests) {
76 83 issue_request(client, test, cmd, args);
77 84 } else {
@@ -84,11 +91,11 @@ function issue_request(client, test, cmd, args) {
84 91
85 92 function test_run(test) {
86 93 create_clients(function() {
87   - var i = num_clients;
88   - var cmd = test.command[0];
89   - var args = test.command.slice(1);
  94 + var i = num_clients,
  95 + cmd = test.command[0],
  96 + args = test.command.slice(1);
90 97
91   - test_start = new Date;
  98 + test_start = Date.now();
92 99 issued_requests = 0;
93 100 while(i-- && issued_requests < num_requests) {
94 101 issue_request(clients[i], test, cmd, args);
@@ -98,7 +105,7 @@ function test_run(test) {
98 105
99 106 function test_complete(test) {
100 107 var min, max, sum, avg;
101   - var total_time = (new Date) - test_start;
  108 + var total_time = Date.now() - test_start;
102 109 var op_rate = (issued_requests / (total_time / 1000.0)).toFixed(2);
103 110 var i;
104 111
@@ -116,8 +123,9 @@ function test_complete(test) {
116 123
117 124 function next() {
118 125 var test = tests.shift();
119   - if (test) test_run(test);
  126 + if (test) {
  127 + test_run(test);
  128 + }
120 129 }
121 130
122 131 next();
123   -
5 package.json
... ... @@ -1,5 +1,5 @@
1 1 { "name" : "redis",
2   - "version" : "0.3.9",
  2 + "version" : "0.4.0",
3 3 "description" : "Redis client library",
4 4 "author": "Matt Ranney <mjr@ranney.com>",
5 5 "contributors": [
@@ -9,7 +9,8 @@
9 9 "Orion Henry",
10 10 "Hank Sims",
11 11 "Aivo Paas",
12   - "Paul Carey"
  12 + "Paul Carey",
  13 + "Pieter Noordhuis"
13 14 ],
14 15 "main": "./index.js",
15 16 "scripts": {
23 test.js
... ... @@ -1,6 +1,8 @@
1 1 /*global require console setTimeout process Buffer */
2 2 var redis = require("./index"),
3   - client = redis.createClient(),
  3 + client = redis.createClient(6379, "127.0.0.1", {
  4 + parser: "javascript"
  5 + }),
4 6 client2 = redis.createClient(),
5 7 client3 = redis.createClient(),
6 8 assert = require("assert"),
@@ -12,7 +14,7 @@ var redis = require("./index"),
12 14 server_info;
13 15
14 16 // Uncomment this to see the wire protocol and other debugging info
15   -//redis.debug_mode = true;
  17 +redis.debug_mode = true;
16 18
17 19 function buffers_to_strings(arr) {
18 20 return arr.map(function (val) {
@@ -149,8 +151,15 @@ tests.MULTI_3 = function () {
149 151 client.sadd("some set", "mem 2");
150 152 client.sadd("some set", "mem 3");
151 153 client.sadd("some set", "mem 4");
  154 +
  155 + // make sure empty mb reply works
  156 + client.del("some missing set");
  157 + client.smembers("some missing set", function (err, reply) {
  158 + // make sure empty mb reply works
  159 + assert.strictEqual(true, is_empty_array(reply), name);
  160 + });
152 161
153   - // test nested multi-bulk replies with nulls.
  162 + // test nested multi-bulk replies with empty mb elements.
154 163 client.multi([
155 164 ["smembers", "some set"],
156 165 ["del", "some set"],
@@ -479,7 +488,7 @@ tests.HGETALL = function () {
479 488 client.HGETALL(["hosts"], function (err, obj) {
480 489 assert.strictEqual(null, err, name + " result sent back unexpected error: " + err);
481 490 assert.strictEqual(3, Object.keys(obj).length, name);
482   - assert.ok(Buffer.isBuffer(obj.mjr), name);
  491 +// assert.ok(Buffer.isBuffer(obj.mjr), name);
483 492 assert.strictEqual("1", obj.mjr.toString(), name);
484 493 assert.strictEqual("23", obj.another.toString(), name);
485 494 assert.strictEqual("1234", obj.home.toString(), name);
@@ -1003,6 +1012,8 @@ function run_next_test() {
1003 1012 }
1004 1013 }
1005 1014
  1015 +console.log("Using reply parser " + client.reply_parser.name);
  1016 +
1006 1017 client.on("connect", function () {
1007 1018 // Fetch and stash info results in case anybody needs info on the server we are using.
1008 1019 client.info(function (err, reply) {
@@ -1018,10 +1029,12 @@ client.on("connect", function () {
1018 1029 obj.versions.push(+num);
1019 1030 });
1020 1031 server_info = obj;
  1032 + console.log("Connected to " + client.host + ":" + client.port + ", Redis server version " + obj.redis_version + "\n");
  1033 +
  1034 + run_next_test();
1021 1035 });
1022 1036
1023 1037 connected = true;
1024   - run_next_test();
1025 1038 });
1026 1039
1027 1040 client.on('end', function () {

0 comments on commit b907364

Please sign in to comment.
Something went wrong with that request. Please try again.