redis 0.10.2 → 0.12.1
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 +8 -2
- package/README.md +12 -22
- package/connection_breaker.js +80 -0
- package/index.js +109 -30
- package/lib/commands.js +9 -1
- package/package.json +1 -1
- package/benches/buffer_bench.js +0 -89
- package/benches/hiredis_parser.js +0 -38
- package/benches/re_sub_test.js +0 -14
- package/benches/reconnect_test.js +0 -29
- package/benches/stress/codec.js +0 -16
- package/benches/stress/pubsub/pub.js +0 -38
- package/benches/stress/pubsub/run +0 -10
- package/benches/stress/pubsub/server.js +0 -23
- package/benches/stress/rpushblpop/pub.js +0 -49
- package/benches/stress/rpushblpop/run +0 -6
- package/benches/stress/rpushblpop/server.js +0 -30
- package/benches/stress/speed/00 +0 -13
- package/benches/stress/speed/plot +0 -13
- package/benches/stress/speed/size-rate.png +0 -0
- package/benches/stress/speed/speed.js +0 -84
- package/benches/sub_quit_test.js +0 -18
- package/changelog.md +0 -316
- package/diff_multi_bench_output.js +0 -90
- package/examples/auth.js +0 -5
- package/examples/backpressure_drain.js +0 -33
- package/examples/eval.js +0 -14
- package/examples/extend.js +0 -24
- package/examples/file.js +0 -32
- package/examples/mget.js +0 -5
- package/examples/monitor.js +0 -10
- package/examples/multi.js +0 -46
- package/examples/multi2.js +0 -29
- package/examples/psubscribe.js +0 -33
- package/examples/pub_sub.js +0 -41
- package/examples/simple.js +0 -24
- package/examples/sort.js +0 -17
- package/examples/subqueries.js +0 -15
- package/examples/subquery.js +0 -19
- package/examples/unix_socket.js +0 -29
- package/examples/web_server.js +0 -31
- package/generate_commands.js +0 -39
- package/multi_bench.js +0 -222
- package/test-unref.js +0 -12
- package/test.js +0 -2257
package/.npmignore
CHANGED
package/README.md
CHANGED
|
@@ -175,10 +175,15 @@ resume sending when you get `drain`.
|
|
|
175
175
|
|
|
176
176
|
`client` will emit `idle` when there are no outstanding commands that are awaiting a response.
|
|
177
177
|
|
|
178
|
-
## redis.createClient(
|
|
178
|
+
## redis.createClient()
|
|
179
179
|
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
### overloading
|
|
181
|
+
* redis.createClient() = redis.createClient(6379, '127.0.0.1', {})
|
|
182
|
+
* redis.createClient(options) = redis.createClient(6379, '127.0.0.1', options)
|
|
183
|
+
* redis.createClient(unix_socket, options)
|
|
184
|
+
* redis.createClient(port, host, options)
|
|
185
|
+
|
|
186
|
+
If you have `redis-server` running on the same computer as node, then the defaults for
|
|
182
187
|
port and host are probably fine. `options` in an object with the following possible properties:
|
|
183
188
|
|
|
184
189
|
* `parser`: which Redis protocol reply parser to use. Defaults to `hiredis` if that module is installed.
|
|
@@ -192,6 +197,7 @@ every command on a client.
|
|
|
192
197
|
* `socket_nodelay`: defaults to `true`. Whether to call setNoDelay() on the TCP stream, which disables the
|
|
193
198
|
Nagle algorithm on the underlying socket. Setting this option to `false` can result in additional throughput at the
|
|
194
199
|
cost of more latency. Most applications will want this set to `true`.
|
|
200
|
+
* `socket_keepalive` defaults to `true`. Whether the keep-alive functionality is enabled on the underlying socket.
|
|
195
201
|
* `no_ready_check`: defaults to `false`. When a connection is established to the Redis server, the server might still
|
|
196
202
|
be loading the database from disk. While loading, the server not respond to any commands. To work around this,
|
|
197
203
|
`node_redis` has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command
|
|
@@ -210,10 +216,12 @@ limits total time for client to reconnect. Value is provided in milliseconds and
|
|
|
210
216
|
* `max_attempts` defaults to `null`. By default client will try reconnecting until connected. Setting `max_attempts`
|
|
211
217
|
limits total amount of reconnects.
|
|
212
218
|
* `auth_pass` defaults to `null`. By default client will try connecting without auth. If set, client will run redis auth command on connect.
|
|
219
|
+
* `family` defaults to `IPv4`. The client connects in IPv4 if not specified or if the DNS resolution returns an IPv4 address.
|
|
220
|
+
You can force an IPv6 if you set the family to 'IPv6'. See nodejs net or dns modules how to use the family type.
|
|
213
221
|
|
|
214
222
|
```js
|
|
215
223
|
var redis = require("redis"),
|
|
216
|
-
client = redis.createClient(
|
|
224
|
+
client = redis.createClient({detect_buffers: true});
|
|
217
225
|
|
|
218
226
|
client.set("foo_rand000000000000", "OK");
|
|
219
227
|
|
|
@@ -231,24 +239,6 @@ limits total amount of reconnects.
|
|
|
231
239
|
|
|
232
240
|
`createClient()` returns a `RedisClient` object that is named `client` in all of the examples here.
|
|
233
241
|
|
|
234
|
-
### Unix Domain Socket
|
|
235
|
-
|
|
236
|
-
You can also create a connection to Redis server via the unix domain socket if the server
|
|
237
|
-
has it enabled:
|
|
238
|
-
|
|
239
|
-
```js
|
|
240
|
-
var redis = require("redis");
|
|
241
|
-
var client = redis.createClient("/tmp/redis.sock");
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
Sample `redis.conf` configuration to enable unix domain socket listening:
|
|
245
|
-
|
|
246
|
-
```conf
|
|
247
|
-
unixsocket /tmp/redis.sock
|
|
248
|
-
unixsocketperm 755
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
See [issue #204](https://github.com/mranney/node_redis/issues/204) for more information.
|
|
252
242
|
|
|
253
243
|
## client.auth(password, callback)
|
|
254
244
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
var net = require('net');
|
|
2
|
+
|
|
3
|
+
var proxyPort = 6379;
|
|
4
|
+
var counter = 0;
|
|
5
|
+
|
|
6
|
+
function breaker(conn) {
|
|
7
|
+
conn.end();
|
|
8
|
+
conn.destroy();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
var server = net.createServer(function(conn) {
|
|
12
|
+
counter++;
|
|
13
|
+
var proxyConn = net.createConnection({
|
|
14
|
+
port: proxyPort
|
|
15
|
+
});
|
|
16
|
+
conn.pipe(proxyConn);
|
|
17
|
+
proxyConn.pipe(conn);
|
|
18
|
+
proxyConn.on('end', function() {
|
|
19
|
+
conn.end();
|
|
20
|
+
});
|
|
21
|
+
conn.on('end', function() {
|
|
22
|
+
proxyConn.end();
|
|
23
|
+
});
|
|
24
|
+
conn.on('close', function() {
|
|
25
|
+
proxyConn.end();
|
|
26
|
+
});
|
|
27
|
+
proxyConn.on('close', function() {
|
|
28
|
+
conn.end();
|
|
29
|
+
});
|
|
30
|
+
proxyConn.on('error', function() {
|
|
31
|
+
conn.end();
|
|
32
|
+
});
|
|
33
|
+
conn.on('error', function() {
|
|
34
|
+
proxyConn.end();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
setTimeout(breaker.bind(null, conn), Math.floor(Math.random() * 2000));
|
|
38
|
+
});
|
|
39
|
+
server.listen(6479);
|
|
40
|
+
|
|
41
|
+
var redis = require('./');
|
|
42
|
+
|
|
43
|
+
var port = 6479;
|
|
44
|
+
|
|
45
|
+
var client = redis.createClient(6479, 'localhost');
|
|
46
|
+
|
|
47
|
+
function iter() {
|
|
48
|
+
var k = "k" + Math.floor(Math.random() * 10);
|
|
49
|
+
var coinflip = Math.random() > 0.5;
|
|
50
|
+
if (coinflip) {
|
|
51
|
+
client.set(k, k, function(err, resp) {
|
|
52
|
+
if (!err && resp !== "OK") {
|
|
53
|
+
console.log("Unexpected set response " + resp);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
client.get(k, function(err, resp) {
|
|
58
|
+
if (!err) {
|
|
59
|
+
if (k !== resp) {
|
|
60
|
+
console.log("Key response mismatch: " + k + " " + resp);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function iters() {
|
|
68
|
+
for (var i = 0; i < 100; ++i) {
|
|
69
|
+
iter();
|
|
70
|
+
}
|
|
71
|
+
setTimeout(iters, 10);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
client.on("connect", function () {
|
|
75
|
+
iters();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
client.on("error", function (err) {
|
|
79
|
+
console.log("Client error " + err);
|
|
80
|
+
});
|
package/index.js
CHANGED
|
@@ -43,6 +43,9 @@ function RedisClient(stream, options) {
|
|
|
43
43
|
if (this.options.socket_nodelay === undefined) {
|
|
44
44
|
this.options.socket_nodelay = true;
|
|
45
45
|
}
|
|
46
|
+
if (this.options.socket_keepalive === undefined) {
|
|
47
|
+
this.options.socket_keepalive = true;
|
|
48
|
+
}
|
|
46
49
|
this.should_buffer = false;
|
|
47
50
|
this.command_queue_high_water = this.options.command_queue_high_water || 1000;
|
|
48
51
|
this.command_queue_low_water = this.options.command_queue_low_water || 0;
|
|
@@ -81,6 +84,14 @@ function RedisClient(stream, options) {
|
|
|
81
84
|
|
|
82
85
|
this.old_state = null;
|
|
83
86
|
|
|
87
|
+
this.install_stream_listeners();
|
|
88
|
+
|
|
89
|
+
events.EventEmitter.call(this);
|
|
90
|
+
}
|
|
91
|
+
util.inherits(RedisClient, events.EventEmitter);
|
|
92
|
+
exports.RedisClient = RedisClient;
|
|
93
|
+
|
|
94
|
+
RedisClient.prototype.install_stream_listeners = function() {
|
|
84
95
|
var self = this;
|
|
85
96
|
|
|
86
97
|
this.stream.on("connect", function () {
|
|
@@ -107,11 +118,7 @@ function RedisClient(stream, options) {
|
|
|
107
118
|
self.should_buffer = false;
|
|
108
119
|
self.emit("drain");
|
|
109
120
|
});
|
|
110
|
-
|
|
111
|
-
events.EventEmitter.call(this);
|
|
112
|
-
}
|
|
113
|
-
util.inherits(RedisClient, events.EventEmitter);
|
|
114
|
-
exports.RedisClient = RedisClient;
|
|
121
|
+
};
|
|
115
122
|
|
|
116
123
|
RedisClient.prototype.initialize_retry_vars = function () {
|
|
117
124
|
this.retry_timer = null;
|
|
@@ -147,7 +154,9 @@ RedisClient.prototype.flush_and_error = function (message) {
|
|
|
147
154
|
try {
|
|
148
155
|
command_obj.callback(error);
|
|
149
156
|
} catch (callback_err) {
|
|
150
|
-
|
|
157
|
+
process.nextTick(function () {
|
|
158
|
+
throw callback_err;
|
|
159
|
+
});
|
|
151
160
|
}
|
|
152
161
|
}
|
|
153
162
|
}
|
|
@@ -159,7 +168,9 @@ RedisClient.prototype.flush_and_error = function (message) {
|
|
|
159
168
|
try {
|
|
160
169
|
command_obj.callback(error);
|
|
161
170
|
} catch (callback_err) {
|
|
162
|
-
|
|
171
|
+
process.nextTick(function () {
|
|
172
|
+
throw callback_err;
|
|
173
|
+
});
|
|
163
174
|
}
|
|
164
175
|
}
|
|
165
176
|
}
|
|
@@ -167,7 +178,7 @@ RedisClient.prototype.flush_and_error = function (message) {
|
|
|
167
178
|
};
|
|
168
179
|
|
|
169
180
|
RedisClient.prototype.on_error = function (msg) {
|
|
170
|
-
var message = "Redis connection to " + this.
|
|
181
|
+
var message = "Redis connection to " + this.address + " failed - " + msg;
|
|
171
182
|
|
|
172
183
|
if (this.closing) {
|
|
173
184
|
return;
|
|
@@ -192,7 +203,7 @@ RedisClient.prototype.do_auth = function () {
|
|
|
192
203
|
var self = this;
|
|
193
204
|
|
|
194
205
|
if (exports.debug_mode) {
|
|
195
|
-
console.log("Sending auth to " + self.
|
|
206
|
+
console.log("Sending auth to " + self.address + " id " + self.connection_id);
|
|
196
207
|
}
|
|
197
208
|
self.send_anyway = true;
|
|
198
209
|
self.send_command("auth", [this.auth_pass], function (err, res) {
|
|
@@ -216,7 +227,7 @@ RedisClient.prototype.do_auth = function () {
|
|
|
216
227
|
return self.emit("error", new Error("Auth failed: " + res.toString()));
|
|
217
228
|
}
|
|
218
229
|
if (exports.debug_mode) {
|
|
219
|
-
console.log("Auth succeeded " + self.
|
|
230
|
+
console.log("Auth succeeded " + self.address + " id " + self.connection_id);
|
|
220
231
|
}
|
|
221
232
|
if (self.auth_callback) {
|
|
222
233
|
self.auth_callback(err, res);
|
|
@@ -238,7 +249,7 @@ RedisClient.prototype.do_auth = function () {
|
|
|
238
249
|
|
|
239
250
|
RedisClient.prototype.on_connect = function () {
|
|
240
251
|
if (exports.debug_mode) {
|
|
241
|
-
console.log("Stream connected " + this.
|
|
252
|
+
console.log("Stream connected " + this.address + " id " + this.connection_id);
|
|
242
253
|
}
|
|
243
254
|
|
|
244
255
|
this.connected = true;
|
|
@@ -249,6 +260,7 @@ RedisClient.prototype.on_connect = function () {
|
|
|
249
260
|
if (this.options.socket_nodelay) {
|
|
250
261
|
this.stream.setNoDelay();
|
|
251
262
|
}
|
|
263
|
+
this.stream.setKeepAlive(this.options.socket_keepalive);
|
|
252
264
|
this.stream.setTimeout(0);
|
|
253
265
|
|
|
254
266
|
this.init_parser();
|
|
@@ -520,14 +532,15 @@ RedisClient.prototype.connection_gone = function (why) {
|
|
|
520
532
|
return;
|
|
521
533
|
}
|
|
522
534
|
|
|
523
|
-
self.stream.
|
|
535
|
+
self.stream = net.createConnection(self.connectionOption);
|
|
536
|
+
self.install_stream_listeners();
|
|
524
537
|
self.retry_timer = null;
|
|
525
538
|
}, this.retry_delay);
|
|
526
539
|
};
|
|
527
540
|
|
|
528
541
|
RedisClient.prototype.on_data = function (data) {
|
|
529
542
|
if (exports.debug_mode) {
|
|
530
|
-
console.log("net read " + this.
|
|
543
|
+
console.log("net read " + this.address + " id " + this.connection_id + ": " + data.toString());
|
|
531
544
|
}
|
|
532
545
|
|
|
533
546
|
try {
|
|
@@ -557,26 +570,37 @@ RedisClient.prototype.return_error = function (err) {
|
|
|
557
570
|
try {
|
|
558
571
|
command_obj.callback(err);
|
|
559
572
|
} catch (callback_err) {
|
|
560
|
-
|
|
573
|
+
// if a callback throws an exception, re-throw it on a new stack so the parser can keep going
|
|
574
|
+
process.nextTick(function () {
|
|
575
|
+
throw callback_err;
|
|
576
|
+
});
|
|
561
577
|
}
|
|
562
578
|
} else {
|
|
563
579
|
console.log("node_redis: no callback to send error: " + err.message);
|
|
564
|
-
this
|
|
580
|
+
// this will probably not make it anywhere useful, but we might as well throw
|
|
581
|
+
process.nextTick(function () {
|
|
582
|
+
throw err;
|
|
583
|
+
});
|
|
565
584
|
}
|
|
566
585
|
};
|
|
567
586
|
|
|
568
587
|
// if a callback throws an exception, re-throw it on a new stack so the parser can keep going.
|
|
569
588
|
// if a domain is active, emit the error on the domain, which will serve the same function.
|
|
570
589
|
// put this try/catch in its own function because V8 doesn't optimize this well yet.
|
|
571
|
-
function try_callback(
|
|
590
|
+
function try_callback(callback, reply) {
|
|
572
591
|
try {
|
|
573
592
|
callback(null, reply);
|
|
574
593
|
} catch (err) {
|
|
575
594
|
if (process.domain) {
|
|
576
|
-
process.domain
|
|
577
|
-
|
|
595
|
+
var currDomain = process.domain;
|
|
596
|
+
currDomain.emit('error', err);
|
|
597
|
+
if (process.domain === currDomain) {
|
|
598
|
+
currDomain.exit();
|
|
599
|
+
}
|
|
578
600
|
} else {
|
|
579
|
-
|
|
601
|
+
process.nextTick(function () {
|
|
602
|
+
throw err;
|
|
603
|
+
});
|
|
580
604
|
}
|
|
581
605
|
}
|
|
582
606
|
}
|
|
@@ -658,7 +682,7 @@ RedisClient.prototype.return_reply = function (reply) {
|
|
|
658
682
|
reply = reply_to_object(reply);
|
|
659
683
|
}
|
|
660
684
|
|
|
661
|
-
try_callback(
|
|
685
|
+
try_callback(command_obj.callback, reply);
|
|
662
686
|
} else if (exports.debug_mode) {
|
|
663
687
|
console.log("no callback for reply: " + (reply && reply.toString && reply.toString()));
|
|
664
688
|
}
|
|
@@ -684,7 +708,7 @@ RedisClient.prototype.return_reply = function (reply) {
|
|
|
684
708
|
// reply[1] can be null
|
|
685
709
|
var reply1String = (reply[1] === null) ? null : reply[1].toString();
|
|
686
710
|
if (command_obj && typeof command_obj.callback === "function") {
|
|
687
|
-
try_callback(
|
|
711
|
+
try_callback(command_obj.callback, reply1String);
|
|
688
712
|
}
|
|
689
713
|
this.emit(type, reply1String, reply[2]); // channel, count
|
|
690
714
|
} else {
|
|
@@ -828,7 +852,7 @@ RedisClient.prototype.send_command = function (command, args, callback) {
|
|
|
828
852
|
command_str += "$" + Buffer.byteLength(arg) + "\r\n" + arg + "\r\n";
|
|
829
853
|
}
|
|
830
854
|
if (exports.debug_mode) {
|
|
831
|
-
console.log("send " + this.
|
|
855
|
+
console.log("send " + this.address + " id " + this.connection_id + ": " + command_str);
|
|
832
856
|
}
|
|
833
857
|
buffered_writes += !stream.write(command_str);
|
|
834
858
|
} else {
|
|
@@ -908,6 +932,14 @@ RedisClient.prototype.pub_sub_command = function (command_obj) {
|
|
|
908
932
|
|
|
909
933
|
RedisClient.prototype.end = function () {
|
|
910
934
|
this.stream._events = {};
|
|
935
|
+
|
|
936
|
+
//clear retry_timer
|
|
937
|
+
if(this.retry_timer){
|
|
938
|
+
clearTimeout(this.retry_timer);
|
|
939
|
+
this.retry_timer=null;
|
|
940
|
+
}
|
|
941
|
+
this.stream.on("error", function(){});
|
|
942
|
+
|
|
911
943
|
this.connected = false;
|
|
912
944
|
this.ready = false;
|
|
913
945
|
this.closing = true;
|
|
@@ -1181,17 +1213,64 @@ RedisClient.prototype.eval = RedisClient.prototype.EVAL = function () {
|
|
|
1181
1213
|
};
|
|
1182
1214
|
|
|
1183
1215
|
|
|
1184
|
-
exports.createClient = function
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1216
|
+
exports.createClient = function(arg0, arg1, arg2){
|
|
1217
|
+
if( arguments.length === 0 ){
|
|
1218
|
+
|
|
1219
|
+
// createClient()
|
|
1220
|
+
return createClient_tcp(default_port, default_host, {});
|
|
1221
|
+
|
|
1222
|
+
} else if( typeof arg0 === 'number' ||
|
|
1223
|
+
typeof arg0 === 'string' && arg0.match(/^\d+$/) ){
|
|
1224
|
+
|
|
1225
|
+
// createClient( 3000, host, options)
|
|
1226
|
+
// createClient('3000', host, options)
|
|
1227
|
+
return createClient_tcp(arg0, arg1, arg2);
|
|
1228
|
+
|
|
1229
|
+
} else if( typeof arg0 === 'string' ){
|
|
1230
|
+
|
|
1231
|
+
// createClient( '/tmp/redis.sock', options)
|
|
1232
|
+
return createClient_unix(arg0,arg1);
|
|
1233
|
+
|
|
1234
|
+
} else if( arg0 !== null && typeof arg0 === 'object' ){
|
|
1235
|
+
|
|
1236
|
+
// createClient(options)
|
|
1237
|
+
return createClient_tcp(default_port, default_host, arg0 );
|
|
1238
|
+
|
|
1239
|
+
} else if( arg0 === null && arg1 === null ){
|
|
1240
|
+
|
|
1241
|
+
// for backward compatibility
|
|
1242
|
+
// createClient(null,null,options)
|
|
1243
|
+
return createClient_tcp(default_port, default_host, arg2);
|
|
1188
1244
|
|
|
1189
|
-
|
|
1245
|
+
} else {
|
|
1246
|
+
throw new Error('unknown type of connection in createClient()');
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
var createClient_unix = function(path, options){
|
|
1251
|
+
var cnxOptions = {
|
|
1252
|
+
path: path
|
|
1253
|
+
};
|
|
1254
|
+
var net_client = net.createConnection(cnxOptions);
|
|
1255
|
+
var redis_client = new RedisClient(net_client, options || {});
|
|
1190
1256
|
|
|
1191
|
-
redis_client =
|
|
1257
|
+
redis_client.connectionOption = cnxOptions;
|
|
1258
|
+
redis_client.address = path;
|
|
1259
|
+
|
|
1260
|
+
return redis_client;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
var createClient_tcp = function (port_arg, host_arg, options) {
|
|
1264
|
+
var cnxOptions = {
|
|
1265
|
+
'port' : port_arg || default_port,
|
|
1266
|
+
'host' : host_arg || default_host,
|
|
1267
|
+
'family' : (options && options.family === 'IPv6') ? 6 : 4
|
|
1268
|
+
};
|
|
1269
|
+
var net_client = net.createConnection(cnxOptions);
|
|
1270
|
+
var redis_client = new RedisClient(net_client, options || {});
|
|
1192
1271
|
|
|
1193
|
-
redis_client.
|
|
1194
|
-
redis_client.
|
|
1272
|
+
redis_client.connectionOption = cnxOptions;
|
|
1273
|
+
redis_client.address = cnxOptions.host + ':' + cnxOptions.port;
|
|
1195
1274
|
|
|
1196
1275
|
return redis_client;
|
|
1197
1276
|
};
|
package/lib/commands.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// This file was generated by ./generate_commands.js on
|
|
1
|
+
// This file was generated by ./generate_commands.js on Wed Apr 23 2014 14:51:21 GMT-0700 (PDT)
|
|
2
2
|
module.exports = [
|
|
3
3
|
"append",
|
|
4
4
|
"auth",
|
|
@@ -6,12 +6,14 @@ module.exports = [
|
|
|
6
6
|
"bgsave",
|
|
7
7
|
"bitcount",
|
|
8
8
|
"bitop",
|
|
9
|
+
"bitpos",
|
|
9
10
|
"blpop",
|
|
10
11
|
"brpop",
|
|
11
12
|
"brpoplpush",
|
|
12
13
|
"client kill",
|
|
13
14
|
"client list",
|
|
14
15
|
"client getname",
|
|
16
|
+
"client pause",
|
|
15
17
|
"client setname",
|
|
16
18
|
"config get",
|
|
17
19
|
"config rewrite",
|
|
@@ -78,6 +80,9 @@ module.exports = [
|
|
|
78
80
|
"persist",
|
|
79
81
|
"pexpire",
|
|
80
82
|
"pexpireat",
|
|
83
|
+
"pfadd",
|
|
84
|
+
"pfcount",
|
|
85
|
+
"pfmerge",
|
|
81
86
|
"ping",
|
|
82
87
|
"psetex",
|
|
83
88
|
"psubscribe",
|
|
@@ -137,10 +142,13 @@ module.exports = [
|
|
|
137
142
|
"zcount",
|
|
138
143
|
"zincrby",
|
|
139
144
|
"zinterstore",
|
|
145
|
+
"zlexcount",
|
|
140
146
|
"zrange",
|
|
147
|
+
"zrangebylex",
|
|
141
148
|
"zrangebyscore",
|
|
142
149
|
"zrank",
|
|
143
150
|
"zrem",
|
|
151
|
+
"zremrangebylex",
|
|
144
152
|
"zremrangebyrank",
|
|
145
153
|
"zremrangebyscore",
|
|
146
154
|
"zrevrange",
|
package/package.json
CHANGED
package/benches/buffer_bench.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
var source = new Buffer(100),
|
|
2
|
-
dest = new Buffer(100), i, j, k, tmp, count = 1000000, bytes = 100;
|
|
3
|
-
|
|
4
|
-
for (i = 99 ; i >= 0 ; i--) {
|
|
5
|
-
source[i] = 120;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
var str = "This is a nice String.",
|
|
9
|
-
buf = new Buffer("This is a lovely Buffer.");
|
|
10
|
-
|
|
11
|
-
var start = new Date();
|
|
12
|
-
for (i = count * 100; i > 0 ; i--) {
|
|
13
|
-
if (Buffer.isBuffer(str)) {}
|
|
14
|
-
}
|
|
15
|
-
var end = new Date();
|
|
16
|
-
console.log("Buffer.isBuffer(str) " + (end - start) + " ms");
|
|
17
|
-
|
|
18
|
-
var start = new Date();
|
|
19
|
-
for (i = count * 100; i > 0 ; i--) {
|
|
20
|
-
if (Buffer.isBuffer(buf)) {}
|
|
21
|
-
}
|
|
22
|
-
var end = new Date();
|
|
23
|
-
console.log("Buffer.isBuffer(buf) " + (end - start) + " ms");
|
|
24
|
-
|
|
25
|
-
var start = new Date();
|
|
26
|
-
for (i = count * 100; i > 0 ; i--) {
|
|
27
|
-
if (str instanceof Buffer) {}
|
|
28
|
-
}
|
|
29
|
-
var end = new Date();
|
|
30
|
-
console.log("str instanceof Buffer " + (end - start) + " ms");
|
|
31
|
-
|
|
32
|
-
var start = new Date();
|
|
33
|
-
for (i = count * 100; i > 0 ; i--) {
|
|
34
|
-
if (buf instanceof Buffer) {}
|
|
35
|
-
}
|
|
36
|
-
var end = new Date();
|
|
37
|
-
console.log("buf instanceof Buffer " + (end - start) + " ms");
|
|
38
|
-
|
|
39
|
-
for (i = bytes ; i > 0 ; i --) {
|
|
40
|
-
var start = new Date();
|
|
41
|
-
for (j = count ; j > 0; j--) {
|
|
42
|
-
tmp = source.toString("ascii", 0, bytes);
|
|
43
|
-
}
|
|
44
|
-
var end = new Date();
|
|
45
|
-
console.log("toString() " + i + " bytes " + (end - start) + " ms");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
for (i = bytes ; i > 0 ; i --) {
|
|
49
|
-
var start = new Date();
|
|
50
|
-
for (j = count ; j > 0; j--) {
|
|
51
|
-
tmp = "";
|
|
52
|
-
for (k = 0; k <= i ; k++) {
|
|
53
|
-
tmp += String.fromCharCode(source[k]);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
var end = new Date();
|
|
57
|
-
console.log("manual string " + i + " bytes " + (end - start) + " ms");
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
for (i = bytes ; i > 0 ; i--) {
|
|
61
|
-
var start = new Date();
|
|
62
|
-
for (j = count ; j > 0 ; j--) {
|
|
63
|
-
for (k = i ; k > 0 ; k--) {
|
|
64
|
-
dest[k] = source[k];
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
var end = new Date();
|
|
68
|
-
console.log("Manual copy " + i + " bytes " + (end - start) + " ms");
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
for (i = bytes ; i > 0 ; i--) {
|
|
72
|
-
var start = new Date();
|
|
73
|
-
for (j = count ; j > 0 ; j--) {
|
|
74
|
-
for (k = i ; k > 0 ; k--) {
|
|
75
|
-
dest[k] = 120;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
var end = new Date();
|
|
79
|
-
console.log("Direct assignment " + i + " bytes " + (end - start) + " ms");
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
for (i = bytes ; i > 0 ; i--) {
|
|
83
|
-
var start = new Date();
|
|
84
|
-
for (j = count ; j > 0 ; j--) {
|
|
85
|
-
source.copy(dest, 0, 0, i);
|
|
86
|
-
}
|
|
87
|
-
var end = new Date();
|
|
88
|
-
console.log("Buffer.copy() " + i + " bytes " + (end - start) + " ms");
|
|
89
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
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
|
-
})();
|
package/benches/re_sub_test.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
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,29 +0,0 @@
|
|
|
1
|
-
var redis = require("../index").createClient(null, null, {
|
|
2
|
-
// max_attempts: 4
|
|
3
|
-
});
|
|
4
|
-
|
|
5
|
-
redis.on("error", function (err) {
|
|
6
|
-
console.log("Redis says: " + err);
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
redis.on("ready", function () {
|
|
10
|
-
console.log("Redis ready.");
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
redis.on("reconnecting", function (arg) {
|
|
14
|
-
console.log("Redis reconnecting: " + JSON.stringify(arg));
|
|
15
|
-
});
|
|
16
|
-
redis.on("connect", function () {
|
|
17
|
-
console.log("Redis connected.");
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
setInterval(function () {
|
|
21
|
-
var now = Date.now();
|
|
22
|
-
redis.set("now", now, function (err, res) {
|
|
23
|
-
if (err) {
|
|
24
|
-
console.log(now + " Redis reply error: " + err);
|
|
25
|
-
} else {
|
|
26
|
-
console.log(now + " Redis reply: " + res);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}, 100);
|
package/benches/stress/codec.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
var json = {
|
|
2
|
-
encode: JSON.stringify,
|
|
3
|
-
decode: JSON.parse
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
var MsgPack = require('node-msgpack');
|
|
7
|
-
msgpack = {
|
|
8
|
-
encode: MsgPack.pack,
|
|
9
|
-
decode: function(str) { return MsgPack.unpack(new Buffer(str)); }
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
bison = require('bison');
|
|
13
|
-
|
|
14
|
-
module.exports = json;
|
|
15
|
-
//module.exports = msgpack;
|
|
16
|
-
//module.exports = bison;
|