redis 0.6.7 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmignore +1 -0
- package/README.md +172 -48
- package/{tests → benches}/buffer_bench.js +0 -0
- package/benches/hiredis_parser.js +38 -0
- package/benches/re_sub_test.js +14 -0
- package/{tests → benches}/reconnect_test.js +4 -2
- package/{tests → benches}/stress/codec.js +0 -0
- package/{tests → benches}/stress/pubsub/pub.js +0 -0
- package/{tests → benches}/stress/pubsub/run +0 -0
- package/{tests → benches}/stress/pubsub/server.js +0 -0
- package/{tests → benches}/stress/rpushblpop/pub.js +0 -0
- package/{tests → benches}/stress/rpushblpop/run +0 -0
- package/{tests → benches}/stress/rpushblpop/server.js +0 -0
- package/{tests → benches}/stress/speed/00 +0 -0
- package/{tests → benches}/stress/speed/plot +0 -0
- package/{tests → benches}/stress/speed/size-rate.png +0 -0
- package/{tests → benches}/stress/speed/speed.js +0 -0
- package/{tests → benches}/sub_quit_test.js +0 -0
- package/changelog.md +35 -0
- package/diff_multi_bench_output.js +87 -0
- package/{eval_test.js → examples/eval.js} +0 -0
- package/examples/simple.js +9 -2
- package/examples/sort.js +17 -0
- package/generate_commands.js +0 -1
- package/index.js +467 -214
- package/lib/commands.js +22 -1
- package/lib/parser/hiredis.js +15 -10
- package/lib/parser/javascript.js +14 -13
- package/lib/queue.js +5 -2
- package/lib/util.js +10 -5
- package/mem.js +11 -0
- package/multi_bench.js +197 -107
- package/package.json +6 -13
- package/test.js +465 -95
- package/simple_test.js +0 -3
- package/tests/test_start_stop.js +0 -17
package/.npmignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
node_modules
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ experimental Redis server branches.
|
|
|
8
8
|
Install with:
|
|
9
9
|
|
|
10
10
|
npm install redis
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
Pieter Noordhuis has provided a binding to the official `hiredis` C library, which is non-blocking and fast. To use `hiredis`, do:
|
|
13
13
|
|
|
14
14
|
npm install hiredis redis
|
|
@@ -23,9 +23,13 @@ happen between node and native code modules after a node upgrade.
|
|
|
23
23
|
|
|
24
24
|
Simple example, included as `examples/simple.js`:
|
|
25
25
|
|
|
26
|
+
```js
|
|
26
27
|
var redis = require("redis"),
|
|
27
28
|
client = redis.createClient();
|
|
28
29
|
|
|
30
|
+
// if you'd like to select database 3, instead of 0 (default), call
|
|
31
|
+
// client.select(3, function() { /* ... */ });
|
|
32
|
+
|
|
29
33
|
client.on("error", function (err) {
|
|
30
34
|
console.log("Error " + err);
|
|
31
35
|
});
|
|
@@ -40,6 +44,7 @@ Simple example, included as `examples/simple.js`:
|
|
|
40
44
|
});
|
|
41
45
|
client.quit();
|
|
42
46
|
});
|
|
47
|
+
```
|
|
43
48
|
|
|
44
49
|
This will display:
|
|
45
50
|
|
|
@@ -50,7 +55,7 @@ This will display:
|
|
|
50
55
|
2 replies:
|
|
51
56
|
0: hashtest 1
|
|
52
57
|
1: hashtest 2
|
|
53
|
-
mjr:~/work/node_redis (master)$
|
|
58
|
+
mjr:~/work/node_redis (master)$
|
|
54
59
|
|
|
55
60
|
|
|
56
61
|
## Performance
|
|
@@ -84,7 +89,7 @@ The performance of `node_redis` improves dramatically with pipelining, which hap
|
|
|
84
89
|
### Sending Commands
|
|
85
90
|
|
|
86
91
|
Each Redis command is exposed as a function on the `client` object.
|
|
87
|
-
All functions take either
|
|
92
|
+
All functions take either an `args` Array plus optional `callback` Function or
|
|
88
93
|
a variable number of individual arguments followed by an optional callback.
|
|
89
94
|
Here is an example of passing an array of arguments and a callback:
|
|
90
95
|
|
|
@@ -93,18 +98,25 @@ Here is an example of passing an array of arguments and a callback:
|
|
|
93
98
|
Here is that same call in the second style:
|
|
94
99
|
|
|
95
100
|
client.mset("test keys 1", "test val 1", "test keys 2", "test val 2", function (err, res) {});
|
|
96
|
-
|
|
101
|
+
|
|
97
102
|
Note that in either form the `callback` is optional:
|
|
98
103
|
|
|
99
104
|
client.set("some key", "some val");
|
|
100
105
|
client.set(["some other key", "some val"]);
|
|
101
106
|
|
|
107
|
+
If the key is missing, reply will be null (probably):
|
|
108
|
+
|
|
109
|
+
client.get("missingkey", function(err, reply) {
|
|
110
|
+
// reply is null when the key is missing
|
|
111
|
+
console.log(reply);
|
|
112
|
+
});
|
|
113
|
+
|
|
102
114
|
For a list of Redis commands, see [Redis Command Reference](http://redis.io/commands)
|
|
103
115
|
|
|
104
116
|
The commands can be specified in uppercase or lowercase for convenience. `client.get()` is the same as `client.GET()`.
|
|
105
117
|
|
|
106
|
-
Minimal parsing is done on the replies. Commands that return a single line reply return JavaScript Strings,
|
|
107
|
-
integer replies return JavaScript Numbers, "bulk" replies return node Buffers, and "multi bulk" replies return a
|
|
118
|
+
Minimal parsing is done on the replies. Commands that return a single line reply return JavaScript Strings,
|
|
119
|
+
integer replies return JavaScript Numbers, "bulk" replies return node Buffers, and "multi bulk" replies return a
|
|
108
120
|
JavaScript Array of node Buffers. `HGETALL` returns an Object with Buffers keyed by the hash keys.
|
|
109
121
|
|
|
110
122
|
# API
|
|
@@ -115,8 +127,8 @@ JavaScript Array of node Buffers. `HGETALL` returns an Object with Buffers keye
|
|
|
115
127
|
|
|
116
128
|
### "ready"
|
|
117
129
|
|
|
118
|
-
`client` will emit `ready` a connection is established to the Redis server and the server reports
|
|
119
|
-
that it is ready to receive commands. Commands issued before the `ready` event are queued,
|
|
130
|
+
`client` will emit `ready` a connection is established to the Redis server and the server reports
|
|
131
|
+
that it is ready to receive commands. Commands issued before the `ready` event are queued,
|
|
120
132
|
then replayed just before this event is emitted.
|
|
121
133
|
|
|
122
134
|
### "connect"
|
|
@@ -129,11 +141,11 @@ you are free to try to send commands.
|
|
|
129
141
|
|
|
130
142
|
`client` will emit `error` when encountering an error connecting to the Redis server.
|
|
131
143
|
|
|
132
|
-
Note that "error" is a special event type in node. If there are no listeners for an
|
|
133
|
-
"error" event, node will exit. This is usually what you want, but it can lead to some
|
|
144
|
+
Note that "error" is a special event type in node. If there are no listeners for an
|
|
145
|
+
"error" event, node will exit. This is usually what you want, but it can lead to some
|
|
134
146
|
cryptic error messages like this:
|
|
135
147
|
|
|
136
|
-
mjr:~/work/node_redis (master)$ node example.js
|
|
148
|
+
mjr:~/work/node_redis (master)$ node example.js
|
|
137
149
|
|
|
138
150
|
node.js:50
|
|
139
151
|
throw e;
|
|
@@ -156,7 +168,7 @@ It would be nice to distinguish these two cases.
|
|
|
156
168
|
|
|
157
169
|
`client` will emit `drain` when the TCP connection to the Redis server has been buffering, but is now
|
|
158
170
|
writable. This event can be used to stream commands in to Redis and adapt to backpressure. Right now,
|
|
159
|
-
you need to check `client.command_queue.length` to decide when to reduce your send rate. Then you can
|
|
171
|
+
you need to check `client.command_queue.length` to decide when to reduce your send rate. Then you can
|
|
160
172
|
resume sending when you get `drain`.
|
|
161
173
|
|
|
162
174
|
### "idle"
|
|
@@ -171,8 +183,43 @@ port and host are probably fine. `options` in an object with the following poss
|
|
|
171
183
|
|
|
172
184
|
* `parser`: which Redis protocol reply parser to use. Defaults to `hiredis` if that module is installed.
|
|
173
185
|
This may also be set to `javascript`.
|
|
174
|
-
* `return_buffers`: defaults to false
|
|
186
|
+
* `return_buffers`: defaults to `false`. If set to `true`, then all replies will be sent to callbacks as node Buffer
|
|
175
187
|
objects instead of JavaScript Strings.
|
|
188
|
+
* `detect_buffers`: default to `false`. If set to `true`, then replies will be sent to callbacks as node Buffer objects
|
|
189
|
+
if any of the input arguments to the original command were Buffer objects.
|
|
190
|
+
This option lets you switch between Buffers and Strings on a per-command basis, whereas `return_buffers` applies to
|
|
191
|
+
every command on a client.
|
|
192
|
+
* `socket_nodelay`: defaults to `true`. Whether to call setNoDelay() on the TCP stream, which disables the
|
|
193
|
+
Nagle algorithm on the underlying socket. Setting this option to `false` can result in additional throughput at the
|
|
194
|
+
cost of more latency. Most applications will want this set to `true`.
|
|
195
|
+
* `no_ready_check`: defaults to `false`. When a connection is established to the Redis server, the server might still
|
|
196
|
+
be loading the database from disk. While loading, the server not respond to any commands. To work around this,
|
|
197
|
+
`node_redis` has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command
|
|
198
|
+
indicates whether the server is ready for more commands. When ready, `node_redis` emits a `ready` event.
|
|
199
|
+
Setting `no_ready_check` to `true` will inhibit this check.
|
|
200
|
+
* `enable_offline_queue`: defaults to `true`. By default, if there is no active
|
|
201
|
+
connection to the redis server, commands are added to a queue and are executed
|
|
202
|
+
once the connection has been established. Setting `enable_offline_queue` to
|
|
203
|
+
`false` will disable this feature and the callback will be execute immediately
|
|
204
|
+
with an error, or an error will be thrown if no callback is specified.
|
|
205
|
+
|
|
206
|
+
```js
|
|
207
|
+
var redis = require("redis"),
|
|
208
|
+
client = redis.createClient(null, null, {detect_buffers: true});
|
|
209
|
+
|
|
210
|
+
client.set("foo_rand000000000000", "OK");
|
|
211
|
+
|
|
212
|
+
// This will return a JavaScript String
|
|
213
|
+
client.get("foo_rand000000000000", function (err, reply) {
|
|
214
|
+
console.log(reply.toString()); // Will print `OK`
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// This will return a Buffer since original key is specified as a Buffer
|
|
218
|
+
client.get(new Buffer("foo_rand000000000000"), function (err, reply) {
|
|
219
|
+
console.log(reply.toString()); // Will print `<Buffer 4f 4b>`
|
|
220
|
+
});
|
|
221
|
+
client.end();
|
|
222
|
+
```
|
|
176
223
|
|
|
177
224
|
`createClient()` returns a `RedisClient` object that is named `client` in all of the examples here.
|
|
178
225
|
|
|
@@ -183,15 +230,19 @@ first command after connecting. This can be tricky to coordinate with reconnect
|
|
|
183
230
|
etc. To make this easier, `client.auth()` stashes `password` and will send it after each connection,
|
|
184
231
|
including reconnections. `callback` is invoked only once, after the response to the very first
|
|
185
232
|
`AUTH` command sent.
|
|
233
|
+
NOTE: Your call to `client.auth()` should not be inside the ready handler. If
|
|
234
|
+
you are doing this wrong, `client` will emit an error that looks
|
|
235
|
+
something like this `Error: Ready check failed: ERR operation not permitted`.
|
|
186
236
|
|
|
187
237
|
## client.end()
|
|
188
238
|
|
|
189
239
|
Forcibly close the connection to the Redis server. Note that this does not wait until all replies have been parsed.
|
|
190
240
|
If you want to exit cleanly, call `client.quit()` to send the `QUIT` command after you have handled all replies.
|
|
191
241
|
|
|
192
|
-
This example closes the connection to the Redis server before the replies have been read. You probably don't
|
|
242
|
+
This example closes the connection to the Redis server before the replies have been read. You probably don't
|
|
193
243
|
want to do this:
|
|
194
244
|
|
|
245
|
+
```js
|
|
195
246
|
var redis = require("redis"),
|
|
196
247
|
client = redis.createClient();
|
|
197
248
|
|
|
@@ -200,17 +251,19 @@ want to do this:
|
|
|
200
251
|
console.log(reply.toString());
|
|
201
252
|
});
|
|
202
253
|
client.end();
|
|
254
|
+
```
|
|
203
255
|
|
|
204
|
-
`client.end()` is useful for timeout cases where something is stuck or taking too long and you want
|
|
256
|
+
`client.end()` is useful for timeout cases where something is stuck or taking too long and you want
|
|
205
257
|
to start over.
|
|
206
258
|
|
|
207
259
|
## Friendlier hash commands
|
|
208
260
|
|
|
209
|
-
Most Redis commands take a single String or an Array of Strings as arguments, and replies are sent back as a single String or an Array of Strings.
|
|
261
|
+
Most Redis commands take a single String or an Array of Strings as arguments, and replies are sent back as a single String or an Array of Strings.
|
|
262
|
+
When dealing with hash values, there are a couple of useful exceptions to this.
|
|
210
263
|
|
|
211
264
|
### client.hgetall(hash)
|
|
212
265
|
|
|
213
|
-
The reply from an HGETALL command will be converted into a JavaScript Object by `node_redis`. That way you can interact
|
|
266
|
+
The reply from an HGETALL command will be converted into a JavaScript Object by `node_redis`. That way you can interact
|
|
214
267
|
with the responses using JavaScript syntax.
|
|
215
268
|
|
|
216
269
|
Example:
|
|
@@ -229,7 +282,7 @@ Output:
|
|
|
229
282
|
Multiple values in a hash can be set by supplying an object:
|
|
230
283
|
|
|
231
284
|
client.HMSET(key2, {
|
|
232
|
-
"0123456789": "abcdefghij",
|
|
285
|
+
"0123456789": "abcdefghij", // NOTE: the key and value must both be strings
|
|
233
286
|
"some manner of key": "a type of value"
|
|
234
287
|
});
|
|
235
288
|
|
|
@@ -245,9 +298,10 @@ Multiple values may also be set by supplying a list:
|
|
|
245
298
|
## Publish / Subscribe
|
|
246
299
|
|
|
247
300
|
Here is a simple example of the API for publish / subscribe. This program opens two
|
|
248
|
-
client connections, subscribes to a channel on one of them, and publishes to that
|
|
301
|
+
client connections, subscribes to a channel on one of them, and publishes to that
|
|
249
302
|
channel on the other:
|
|
250
303
|
|
|
304
|
+
```js
|
|
251
305
|
var redis = require("redis"),
|
|
252
306
|
client1 = redis.createClient(), client2 = redis.createClient(),
|
|
253
307
|
msg_count = 0;
|
|
@@ -270,9 +324,10 @@ channel on the other:
|
|
|
270
324
|
|
|
271
325
|
client1.incr("did a thing");
|
|
272
326
|
client1.subscribe("a nice channel");
|
|
327
|
+
```
|
|
273
328
|
|
|
274
329
|
When a client issues a `SUBSCRIBE` or `PSUBSCRIBE`, that connection is put into "pub/sub" mode.
|
|
275
|
-
At that point, only commands that modify the subscription set are valid. When the subscription
|
|
330
|
+
At that point, only commands that modify the subscription set are valid. When the subscription
|
|
276
331
|
set is empty, the connection is put back into regular mode.
|
|
277
332
|
|
|
278
333
|
If you need to send regular commands to Redis while in pub/sub mode, just open another connection.
|
|
@@ -294,23 +349,23 @@ name as `channel`, and the message Buffer as `message`.
|
|
|
294
349
|
|
|
295
350
|
### "subscribe" (channel, count)
|
|
296
351
|
|
|
297
|
-
Client will emit `subscribe` in response to a `SUBSCRIBE` command. Listeners are passed the
|
|
352
|
+
Client will emit `subscribe` in response to a `SUBSCRIBE` command. Listeners are passed the
|
|
298
353
|
channel name as `channel` and the new count of subscriptions for this client as `count`.
|
|
299
354
|
|
|
300
|
-
### "psubscribe" (pattern, count)
|
|
355
|
+
### "psubscribe" (pattern, count)
|
|
301
356
|
|
|
302
357
|
Client will emit `psubscribe` in response to a `PSUBSCRIBE` command. Listeners are passed the
|
|
303
358
|
original pattern as `pattern`, and the new count of subscriptions for this client as `count`.
|
|
304
359
|
|
|
305
360
|
### "unsubscribe" (channel, count)
|
|
306
361
|
|
|
307
|
-
Client will emit `unsubscribe` in response to a `UNSUBSCRIBE` command. Listeners are passed the
|
|
362
|
+
Client will emit `unsubscribe` in response to a `UNSUBSCRIBE` command. Listeners are passed the
|
|
308
363
|
channel name as `channel` and the new count of subscriptions for this client as `count`. When
|
|
309
364
|
`count` is 0, this client has left pub/sub mode and no more pub/sub events will be emitted.
|
|
310
365
|
|
|
311
366
|
### "punsubscribe" (pattern, count)
|
|
312
367
|
|
|
313
|
-
Client will emit `punsubscribe` in response to a `PUNSUBSCRIBE` command. Listeners are passed the
|
|
368
|
+
Client will emit `punsubscribe` in response to a `PUNSUBSCRIBE` command. Listeners are passed the
|
|
314
369
|
channel name as `channel` and the new count of subscriptions for this client as `count`. When
|
|
315
370
|
`count` is 0, this client has left pub/sub mode and no more pub/sub events will be emitted.
|
|
316
371
|
|
|
@@ -319,6 +374,7 @@ channel name as `channel` and the new count of subscriptions for this client as
|
|
|
319
374
|
`MULTI` commands are queued up until an `EXEC` is issued, and then all commands are run atomically by
|
|
320
375
|
Redis. The interface in `node_redis` is to return an individual `Multi` object by calling `client.multi()`.
|
|
321
376
|
|
|
377
|
+
```js
|
|
322
378
|
var redis = require("./index"),
|
|
323
379
|
client = redis.createClient(), set_size = 20;
|
|
324
380
|
|
|
@@ -335,6 +391,8 @@ Redis. The interface in `node_redis` is to return an individual `Multi` object
|
|
|
335
391
|
.scard("bigset")
|
|
336
392
|
.smembers("bigset")
|
|
337
393
|
.keys("*", function (err, replies) {
|
|
394
|
+
// NOTE: code in this callback is NOT atomic
|
|
395
|
+
// this only happens after the the .exec call finishes.
|
|
338
396
|
client.mget(replies, redis.print);
|
|
339
397
|
})
|
|
340
398
|
.dbsize()
|
|
@@ -344,6 +402,7 @@ Redis. The interface in `node_redis` is to return an individual `Multi` object
|
|
|
344
402
|
console.log("Reply " + index + ": " + reply.toString());
|
|
345
403
|
});
|
|
346
404
|
});
|
|
405
|
+
```
|
|
347
406
|
|
|
348
407
|
`client.multi()` is a constructor that returns a `Multi` object. `Multi` objects share all of the
|
|
349
408
|
same command methods as `client` objects do. Commands are queued up inside the `Multi` object
|
|
@@ -352,10 +411,11 @@ until `Multi.exec()` is invoked.
|
|
|
352
411
|
You can either chain together `MULTI` commands as in the above example, or you can queue individual
|
|
353
412
|
commands while still sending regular client command as in this example:
|
|
354
413
|
|
|
414
|
+
```js
|
|
355
415
|
var redis = require("redis"),
|
|
356
416
|
client = redis.createClient(), multi;
|
|
357
417
|
|
|
358
|
-
// start a separate multi command queue
|
|
418
|
+
// start a separate multi command queue
|
|
359
419
|
multi = client.multi();
|
|
360
420
|
multi.incr("incr thing", redis.print);
|
|
361
421
|
multi.incr("incr other thing", redis.print);
|
|
@@ -373,10 +433,12 @@ commands while still sending regular client command as in this example:
|
|
|
373
433
|
console.log(replies); // 102, 3
|
|
374
434
|
client.quit();
|
|
375
435
|
});
|
|
436
|
+
```
|
|
376
437
|
|
|
377
|
-
In addition to adding commands to the `MULTI` queue individually, you can also pass an array
|
|
438
|
+
In addition to adding commands to the `MULTI` queue individually, you can also pass an array
|
|
378
439
|
of commands and arguments to the constructor:
|
|
379
440
|
|
|
441
|
+
```js
|
|
380
442
|
var redis = require("redis"),
|
|
381
443
|
client = redis.createClient(), multi;
|
|
382
444
|
|
|
@@ -387,6 +449,7 @@ of commands and arguments to the constructor:
|
|
|
387
449
|
]).exec(function (err, replies) {
|
|
388
450
|
console.log(replies);
|
|
389
451
|
});
|
|
452
|
+
```
|
|
390
453
|
|
|
391
454
|
|
|
392
455
|
## Monitor mode
|
|
@@ -395,11 +458,12 @@ Redis supports the `MONITOR` command, which lets you see all commands received b
|
|
|
395
458
|
across all client connections, including from other client libraries and other computers.
|
|
396
459
|
|
|
397
460
|
After you send the `MONITOR` command, no other commands are valid on that connection. `node_redis`
|
|
398
|
-
will emit a `monitor` event for every new monitor message that comes across. The callback for the
|
|
461
|
+
will emit a `monitor` event for every new monitor message that comes across. The callback for the
|
|
399
462
|
`monitor` event takes a timestamp from the Redis server and an array of command arguments.
|
|
400
463
|
|
|
401
464
|
Here is a simple example:
|
|
402
465
|
|
|
466
|
+
```js
|
|
403
467
|
var client = require("redis").createClient(),
|
|
404
468
|
util = require("util");
|
|
405
469
|
|
|
@@ -410,7 +474,7 @@ Here is a simple example:
|
|
|
410
474
|
client.on("monitor", function (time, args) {
|
|
411
475
|
console.log(time + ": " + util.inspect(args));
|
|
412
476
|
});
|
|
413
|
-
|
|
477
|
+
```
|
|
414
478
|
|
|
415
479
|
# Extras
|
|
416
480
|
|
|
@@ -418,7 +482,7 @@ Some other things you might like to know about.
|
|
|
418
482
|
|
|
419
483
|
## client.server_info
|
|
420
484
|
|
|
421
|
-
After the ready probe completes, the results from the INFO command are saved in the `client.server_info`
|
|
485
|
+
After the ready probe completes, the results from the INFO command are saved in the `client.server_info`
|
|
422
486
|
object.
|
|
423
487
|
|
|
424
488
|
The `versions` key contains an array of the elements of the version string for easy comparison.
|
|
@@ -432,6 +496,7 @@ The `versions` key contains an array of the elements of the version string for e
|
|
|
432
496
|
|
|
433
497
|
A handy callback function for displaying return values when testing. Example:
|
|
434
498
|
|
|
499
|
+
```js
|
|
435
500
|
var redis = require("redis"),
|
|
436
501
|
client = redis.createClient();
|
|
437
502
|
|
|
@@ -439,6 +504,7 @@ A handy callback function for displaying return values when testing. Example:
|
|
|
439
504
|
client.set("foo_rand000000000000", "some fantastic value", redis.print);
|
|
440
505
|
client.get("foo_rand000000000000", redis.print);
|
|
441
506
|
});
|
|
507
|
+
```
|
|
442
508
|
|
|
443
509
|
This will print:
|
|
444
510
|
|
|
@@ -451,6 +517,7 @@ Note that this program will not exit cleanly because the client is still connect
|
|
|
451
517
|
|
|
452
518
|
Boolean to enable debug mode and protocol tracing.
|
|
453
519
|
|
|
520
|
+
```js
|
|
454
521
|
var redis = require("redis"),
|
|
455
522
|
client = redis.createClient();
|
|
456
523
|
|
|
@@ -459,10 +526,11 @@ Boolean to enable debug mode and protocol tracing.
|
|
|
459
526
|
client.on("connect", function () {
|
|
460
527
|
client.set("foo_rand000000000000", "some fantastic value");
|
|
461
528
|
});
|
|
529
|
+
```
|
|
462
530
|
|
|
463
531
|
This will display:
|
|
464
532
|
|
|
465
|
-
mjr:~/work/node_redis (master)$ node ~/example.js
|
|
533
|
+
mjr:~/work/node_redis (master)$ node ~/example.js
|
|
466
534
|
send command: *3
|
|
467
535
|
$3
|
|
468
536
|
SET
|
|
@@ -477,12 +545,11 @@ This will display:
|
|
|
477
545
|
|
|
478
546
|
## client.send_command(command_name, args, callback)
|
|
479
547
|
|
|
480
|
-
Used internally to send commands to Redis. For convenience, nearly all commands that are published on the Redis
|
|
548
|
+
Used internally to send commands to Redis. For convenience, nearly all commands that are published on the Redis
|
|
481
549
|
Wiki have been added to the `client` object. However, if I missed any, or if new commands are introduced before
|
|
482
550
|
this library is updated, you can use `send_command()` to send arbitrary commands to Redis.
|
|
483
551
|
|
|
484
|
-
All commands are sent as multi-bulk commands. `args` can either be an Array of arguments, or
|
|
485
|
-
or omitted completely.
|
|
552
|
+
All commands are sent as multi-bulk commands. `args` can either be an Array of arguments, or omitted.
|
|
486
553
|
|
|
487
554
|
## client.connected
|
|
488
555
|
|
|
@@ -490,7 +557,7 @@ Boolean tracking the state of the connection to the Redis server.
|
|
|
490
557
|
|
|
491
558
|
## client.command_queue.length
|
|
492
559
|
|
|
493
|
-
The number of commands that have been sent to the Redis server but not yet replied to. You can use this to
|
|
560
|
+
The number of commands that have been sent to the Redis server but not yet replied to. You can use this to
|
|
494
561
|
enforce some kind of maximum queue depth for commands while connected.
|
|
495
562
|
|
|
496
563
|
Don't mess with `client.command_queue` though unless you really know what you are doing.
|
|
@@ -509,10 +576,38 @@ Current delay in milliseconds before a connection retry will be attempted. This
|
|
|
509
576
|
Multiplier for future retry timeouts. This should be larger than 1 to add more time between retries.
|
|
510
577
|
Defaults to 1.7. The default initial connection retry is 250, so the second retry will be 425, followed by 723.5, etc.
|
|
511
578
|
|
|
579
|
+
### Commands with Optional and Keyword arguments
|
|
580
|
+
|
|
581
|
+
This applies to anything that uses an optional `[WITHSCORES]` or `[LIMIT offset count]` in the [redis.io/commands](http://redis.io/commands) documentation.
|
|
582
|
+
|
|
583
|
+
Example:
|
|
584
|
+
```js
|
|
585
|
+
var args = [ 'myzset', 1, 'one', 2, 'two', 3, 'three', 99, 'ninety-nine' ];
|
|
586
|
+
client.zadd(args, function (err, response) {
|
|
587
|
+
if (err) throw err;
|
|
588
|
+
console.log('added '+response+' items.');
|
|
589
|
+
|
|
590
|
+
// -Infinity and +Infinity also work
|
|
591
|
+
var args1 = [ 'myzset', '+inf', '-inf' ];
|
|
592
|
+
client.zrevrangebyscore(args1, function (err, response) {
|
|
593
|
+
if (err) throw err;
|
|
594
|
+
console.log('example1', response);
|
|
595
|
+
// write your code here
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
var max = 3, min = 1, offset = 1, count = 2;
|
|
599
|
+
var args2 = [ 'myzset', max, min, 'WITHSCORES', 'LIMIT', offset, count ];
|
|
600
|
+
client.zrevrangebyscore(args2, function (err, response) {
|
|
601
|
+
if (err) throw err;
|
|
602
|
+
console.log('example2', response);
|
|
603
|
+
// write your code here
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
```
|
|
512
607
|
|
|
513
608
|
## TODO
|
|
514
609
|
|
|
515
|
-
Better tests for
|
|
610
|
+
Better tests for auth, disconnect/reconnect, and all combinations thereof.
|
|
516
611
|
|
|
517
612
|
Stream large set/get values into and out of Redis. Otherwise the entire value must be in node's memory.
|
|
518
613
|
|
|
@@ -520,22 +615,51 @@ Performance can be better for very large values.
|
|
|
520
615
|
|
|
521
616
|
I think there are more performance improvements left in there for smaller values, especially for large lists of small values.
|
|
522
617
|
|
|
523
|
-
##
|
|
618
|
+
## How to Contribute
|
|
619
|
+
- open a pull request and then wait for feedback (if
|
|
620
|
+
[DTrejo](http://github.com/dtrejo) does not get back to you within 2 days,
|
|
621
|
+
comment again with indignation!)
|
|
524
622
|
|
|
623
|
+
## Contributors
|
|
525
624
|
Some people have have added features and fixed bugs in `node_redis` other than me.
|
|
526
625
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
626
|
+
Ordered by date of first contribution.
|
|
627
|
+
[Auto-generated](http://github.com/dtrejo/node-authors) on Wed Jul 25 2012 19:14:59 GMT-0700 (PDT).
|
|
628
|
+
|
|
629
|
+
- [Matt Ranney aka `mranney`](https://github.com/mranney)
|
|
630
|
+
- [Tim-Smart aka `tim-smart`](https://github.com/tim-smart)
|
|
631
|
+
- [Tj Holowaychuk aka `visionmedia`](https://github.com/visionmedia)
|
|
632
|
+
- [rick aka `technoweenie`](https://github.com/technoweenie)
|
|
633
|
+
- [Orion Henry aka `orionz`](https://github.com/orionz)
|
|
634
|
+
- [Aivo Paas aka `aivopaas`](https://github.com/aivopaas)
|
|
635
|
+
- [Hank Sims aka `hanksims`](https://github.com/hanksims)
|
|
636
|
+
- [Paul Carey aka `paulcarey`](https://github.com/paulcarey)
|
|
637
|
+
- [Pieter Noordhuis aka `pietern`](https://github.com/pietern)
|
|
638
|
+
- [nithesh aka `nithesh`](https://github.com/nithesh)
|
|
639
|
+
- [Andy Ray aka `andy2ray`](https://github.com/andy2ray)
|
|
640
|
+
- [unknown aka `unknowdna`](https://github.com/unknowdna)
|
|
641
|
+
- [Dave Hoover aka `redsquirrel`](https://github.com/redsquirrel)
|
|
642
|
+
- [Vladimir Dronnikov aka `dvv`](https://github.com/dvv)
|
|
643
|
+
- [Umair Siddique aka `umairsiddique`](https://github.com/umairsiddique)
|
|
644
|
+
- [Louis-Philippe Perron aka `lp`](https://github.com/lp)
|
|
645
|
+
- [Mark Dawson aka `markdaws`](https://github.com/markdaws)
|
|
646
|
+
- [Ian Babrou aka `bobrik`](https://github.com/bobrik)
|
|
647
|
+
- [Felix Geisendörfer aka `felixge`](https://github.com/felixge)
|
|
648
|
+
- [Jean-Hugues Pinson aka `undefined`](https://github.com/undefined)
|
|
649
|
+
- [Maksim Lin aka `maks`](https://github.com/maks)
|
|
650
|
+
- [Owen Smith aka `orls`](https://github.com/orls)
|
|
651
|
+
- [Zachary Scott aka `zzak`](https://github.com/zzak)
|
|
652
|
+
- [TEHEK Firefox aka `TEHEK`](https://github.com/TEHEK)
|
|
653
|
+
- [Isaac Z. Schlueter aka `isaacs`](https://github.com/isaacs)
|
|
654
|
+
- [David Trejo aka `DTrejo`](https://github.com/DTrejo)
|
|
655
|
+
- [Brian Noguchi aka `bnoguchi`](https://github.com/bnoguchi)
|
|
656
|
+
- [Philip Tellis aka `bluesmoon`](https://github.com/bluesmoon)
|
|
657
|
+
- [Marcus Westin aka `marcuswestin2`](https://github.com/marcuswestin2)
|
|
658
|
+
- [Jed Schmidt aka `jed`](https://github.com/jed)
|
|
659
|
+
- [Dave Peticolas aka `jdavisp3`](https://github.com/jdavisp3)
|
|
660
|
+
- [Trae Robrock aka `trobrock`](https://github.com/trobrock)
|
|
661
|
+
- [Shankar Karuppiah aka `shankar0306`](https://github.com/shankar0306)
|
|
662
|
+
- [Ignacio Burgueño aka `ignacio`](https://github.com/ignacio)
|
|
539
663
|
|
|
540
664
|
Thanks.
|
|
541
665
|
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var Parser = require('../lib/parser/hiredis').Parser;
|
|
2
|
+
var assert = require('assert');
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
This test makes sure that exceptions thrown inside of "reply" event handlers
|
|
6
|
+
are not trapped and mistakenly emitted as parse errors.
|
|
7
|
+
*/
|
|
8
|
+
(function testExecuteDoesNotCatchReplyCallbackExceptions() {
|
|
9
|
+
var parser = new Parser();
|
|
10
|
+
var replies = [{}];
|
|
11
|
+
|
|
12
|
+
parser.reader = {
|
|
13
|
+
feed: function() {},
|
|
14
|
+
get: function() {
|
|
15
|
+
return replies.shift();
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
var emittedError = false;
|
|
20
|
+
var caughtException = false;
|
|
21
|
+
|
|
22
|
+
parser
|
|
23
|
+
.on('error', function() {
|
|
24
|
+
emittedError = true;
|
|
25
|
+
})
|
|
26
|
+
.on('reply', function() {
|
|
27
|
+
throw new Error('bad');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
parser.execute();
|
|
32
|
+
} catch (err) {
|
|
33
|
+
caughtException = true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
assert.equal(caughtException, true);
|
|
37
|
+
assert.equal(emittedError, false);
|
|
38
|
+
})();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
var client = require('../index').createClient()
|
|
2
|
+
, client2 = require('../index').createClient()
|
|
3
|
+
, assert = require('assert');
|
|
4
|
+
|
|
5
|
+
client.once('subscribe', function (channel, count) {
|
|
6
|
+
client.unsubscribe('x');
|
|
7
|
+
client.subscribe('x', function () {
|
|
8
|
+
client.quit();
|
|
9
|
+
client2.quit();
|
|
10
|
+
});
|
|
11
|
+
client2.publish('x', 'hi');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
client.subscribe('x');
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
var redis = require("
|
|
1
|
+
var redis = require("../index").createClient(null, null, {
|
|
2
|
+
// max_attempts: 4
|
|
3
|
+
});
|
|
2
4
|
|
|
3
5
|
redis.on("error", function (err) {
|
|
4
6
|
console.log("Redis says: " + err);
|
|
@@ -24,4 +26,4 @@ setInterval(function () {
|
|
|
24
26
|
console.log(now + " Redis reply: " + res);
|
|
25
27
|
}
|
|
26
28
|
});
|
|
27
|
-
},
|
|
29
|
+
}, 100);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/changelog.md
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
## v0.7.2 - April 29, 2012
|
|
5
|
+
|
|
6
|
+
Many contributed fixes. Thank you, contributors.
|
|
7
|
+
|
|
8
|
+
* [GH-190] - pub/sub mode fix (Brian Noguchi)
|
|
9
|
+
* [GH-165] - parser selection fix (TEHEK)
|
|
10
|
+
* numerous documentation and examples updates
|
|
11
|
+
* auth errors emit Errors instead of Strings (David Trejo)
|
|
12
|
+
|
|
13
|
+
## v0.7.1 - November 15, 2011
|
|
14
|
+
|
|
15
|
+
Fix regression in reconnect logic.
|
|
16
|
+
|
|
17
|
+
Very much need automated tests for reconnection and queue logic.
|
|
18
|
+
|
|
19
|
+
## v0.7.0 - November 14, 2011
|
|
20
|
+
|
|
21
|
+
Many contributed fixes. Thanks everybody.
|
|
22
|
+
|
|
23
|
+
* [GH-127] - properly re-initialize parser on reconnect
|
|
24
|
+
* [GH-136] - handle passing undefined as callback (Ian Babrou)
|
|
25
|
+
* [GH-139] - properly handle exceptions thrown in pub/sub event handlers (Felix Geisendörfer)
|
|
26
|
+
* [GH-141] - detect closing state on stream error (Felix Geisendörfer)
|
|
27
|
+
* [GH-142] - re-select database on reconnection (Jean-Hugues Pinson)
|
|
28
|
+
* [GH-146] - add sort example (Maksim Lin)
|
|
29
|
+
|
|
30
|
+
Some more goodies:
|
|
31
|
+
|
|
32
|
+
* Fix bugs with node 0.6
|
|
33
|
+
* Performance improvements
|
|
34
|
+
* New version of `multi_bench.js` that tests more realistic scenarios
|
|
35
|
+
* [GH-140] - support optional callback for subscribe commands
|
|
36
|
+
* Properly flush and error out command queue when connection fails
|
|
37
|
+
* Initial work on reconnection thresholds
|
|
38
|
+
|
|
4
39
|
## v0.6.7 - July 30, 2011
|
|
5
40
|
|
|
6
41
|
(accidentally skipped v0.6.6)
|