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/lib/commands.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
// This file was generated by ./generate_commands.js on
|
|
1
|
+
// This file was generated by ./generate_commands.js on Mon Aug 06 2012 15:04:06 GMT-0700 (PDT)
|
|
2
2
|
module.exports = [
|
|
3
3
|
"append",
|
|
4
4
|
"auth",
|
|
5
5
|
"bgrewriteaof",
|
|
6
6
|
"bgsave",
|
|
7
|
+
"bitcount",
|
|
8
|
+
"bitop",
|
|
7
9
|
"blpop",
|
|
8
10
|
"brpop",
|
|
9
11
|
"brpoplpush",
|
|
12
|
+
"client kill",
|
|
13
|
+
"client list",
|
|
10
14
|
"config get",
|
|
11
15
|
"config set",
|
|
12
16
|
"config resetstat",
|
|
@@ -17,7 +21,10 @@ module.exports = [
|
|
|
17
21
|
"decrby",
|
|
18
22
|
"del",
|
|
19
23
|
"discard",
|
|
24
|
+
"dump",
|
|
20
25
|
"echo",
|
|
26
|
+
"eval",
|
|
27
|
+
"evalsha",
|
|
21
28
|
"exec",
|
|
22
29
|
"exists",
|
|
23
30
|
"expire",
|
|
@@ -33,6 +40,7 @@ module.exports = [
|
|
|
33
40
|
"hget",
|
|
34
41
|
"hgetall",
|
|
35
42
|
"hincrby",
|
|
43
|
+
"hincrbyfloat",
|
|
36
44
|
"hkeys",
|
|
37
45
|
"hlen",
|
|
38
46
|
"hmget",
|
|
@@ -42,6 +50,7 @@ module.exports = [
|
|
|
42
50
|
"hvals",
|
|
43
51
|
"incr",
|
|
44
52
|
"incrby",
|
|
53
|
+
"incrbyfloat",
|
|
45
54
|
"info",
|
|
46
55
|
"keys",
|
|
47
56
|
"lastsave",
|
|
@@ -56,6 +65,7 @@ module.exports = [
|
|
|
56
65
|
"lset",
|
|
57
66
|
"ltrim",
|
|
58
67
|
"mget",
|
|
68
|
+
"migrate",
|
|
59
69
|
"monitor",
|
|
60
70
|
"move",
|
|
61
71
|
"mset",
|
|
@@ -63,14 +73,19 @@ module.exports = [
|
|
|
63
73
|
"multi",
|
|
64
74
|
"object",
|
|
65
75
|
"persist",
|
|
76
|
+
"pexpire",
|
|
77
|
+
"pexpireat",
|
|
66
78
|
"ping",
|
|
79
|
+
"psetex",
|
|
67
80
|
"psubscribe",
|
|
81
|
+
"pttl",
|
|
68
82
|
"publish",
|
|
69
83
|
"punsubscribe",
|
|
70
84
|
"quit",
|
|
71
85
|
"randomkey",
|
|
72
86
|
"rename",
|
|
73
87
|
"renamenx",
|
|
88
|
+
"restore",
|
|
74
89
|
"rpop",
|
|
75
90
|
"rpoplpush",
|
|
76
91
|
"rpush",
|
|
@@ -78,6 +93,10 @@ module.exports = [
|
|
|
78
93
|
"sadd",
|
|
79
94
|
"save",
|
|
80
95
|
"scard",
|
|
96
|
+
"script exists",
|
|
97
|
+
"script flush",
|
|
98
|
+
"script kill",
|
|
99
|
+
"script load",
|
|
81
100
|
"sdiff",
|
|
82
101
|
"sdiffstore",
|
|
83
102
|
"select",
|
|
@@ -91,6 +110,7 @@ module.exports = [
|
|
|
91
110
|
"sinterstore",
|
|
92
111
|
"sismember",
|
|
93
112
|
"slaveof",
|
|
113
|
+
"slowlog",
|
|
94
114
|
"smembers",
|
|
95
115
|
"smove",
|
|
96
116
|
"sort",
|
|
@@ -102,6 +122,7 @@ module.exports = [
|
|
|
102
122
|
"sunion",
|
|
103
123
|
"sunionstore",
|
|
104
124
|
"sync",
|
|
125
|
+
"time",
|
|
105
126
|
"ttl",
|
|
106
127
|
"type",
|
|
107
128
|
"unsubscribe",
|
package/lib/parser/hiredis.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*global Buffer require exports console setTimeout */
|
|
2
2
|
|
|
3
3
|
var events = require("events"),
|
|
4
|
-
util = require("../util")
|
|
4
|
+
util = require("../util"),
|
|
5
5
|
hiredis = require("hiredis");
|
|
6
6
|
|
|
7
7
|
exports.debug_mode = false;
|
|
@@ -27,15 +27,20 @@ HiredisReplyParser.prototype.reset = function () {
|
|
|
27
27
|
HiredisReplyParser.prototype.execute = function (data) {
|
|
28
28
|
var reply;
|
|
29
29
|
this.reader.feed(data);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
while (true) {
|
|
31
|
+
try {
|
|
32
|
+
reply = this.reader.get();
|
|
33
|
+
} catch (err) {
|
|
34
|
+
this.emit("error", err);
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (reply === undefined) break;
|
|
39
|
+
|
|
40
|
+
if (reply && reply.constructor === Error) {
|
|
41
|
+
this.emit("reply error", reply);
|
|
42
|
+
} else {
|
|
43
|
+
this.emit("reply", reply);
|
|
37
44
|
}
|
|
38
|
-
} catch (err) {
|
|
39
|
-
this.emit("error", err);
|
|
40
45
|
}
|
|
41
46
|
};
|
package/lib/parser/javascript.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// use numbers for parser state
|
|
7
7
|
|
|
8
8
|
var events = require("events"),
|
|
9
|
-
util = require("../util")
|
|
9
|
+
util = require("../util");
|
|
10
10
|
|
|
11
11
|
exports.debug_mode = false;
|
|
12
12
|
exports.name = "javascript";
|
|
@@ -56,7 +56,8 @@ RedisReplyParser.prototype.reset = function () {
|
|
|
56
56
|
UNKNOWN_TYPE: 8,
|
|
57
57
|
FINAL_CR: 9,
|
|
58
58
|
FINAL_LF: 10,
|
|
59
|
-
MULTI_BULK_COUNT_LF: 11
|
|
59
|
+
MULTI_BULK_COUNT_LF: 11,
|
|
60
|
+
BULK_LF: 12
|
|
60
61
|
};
|
|
61
62
|
|
|
62
63
|
this.state = this.states.TYPE;
|
|
@@ -77,7 +78,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
77
78
|
// console.log("execute: " + this.state + ", " + pos + "/" + incoming_buf.length + ", " + String.fromCharCode(incoming_buf[pos]));
|
|
78
79
|
|
|
79
80
|
switch (this.state) {
|
|
80
|
-
case states.TYPE
|
|
81
|
+
case 1: // states.TYPE
|
|
81
82
|
this.type = incoming_buf[pos];
|
|
82
83
|
pos += 1;
|
|
83
84
|
|
|
@@ -109,7 +110,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
109
110
|
this.state = states.UNKNOWN_TYPE;
|
|
110
111
|
}
|
|
111
112
|
break;
|
|
112
|
-
case states.INTEGER_LINE
|
|
113
|
+
case 4: // states.INTEGER_LINE
|
|
113
114
|
if (incoming_buf[pos] === 13) {
|
|
114
115
|
this.send_reply(+small_toString(this.return_buffer, this.return_buffer.end));
|
|
115
116
|
this.state = states.FINAL_LF;
|
|
@@ -119,7 +120,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
119
120
|
}
|
|
120
121
|
pos += 1;
|
|
121
122
|
break;
|
|
122
|
-
case states.ERROR_LINE
|
|
123
|
+
case 6: // states.ERROR_LINE
|
|
123
124
|
if (incoming_buf[pos] === 13) {
|
|
124
125
|
this.send_error(this.return_buffer.toString("ascii", 0, this.return_buffer.end));
|
|
125
126
|
this.state = states.FINAL_LF;
|
|
@@ -129,7 +130,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
129
130
|
}
|
|
130
131
|
pos += 1;
|
|
131
132
|
break;
|
|
132
|
-
case states.SINGLE_LINE
|
|
133
|
+
case 2: // states.SINGLE_LINE
|
|
133
134
|
if (incoming_buf[pos] === 13) {
|
|
134
135
|
this.send_reply(this.return_string);
|
|
135
136
|
this.state = states.FINAL_LF;
|
|
@@ -138,7 +139,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
138
139
|
}
|
|
139
140
|
pos += 1;
|
|
140
141
|
break;
|
|
141
|
-
case states.MULTI_BULK_COUNT
|
|
142
|
+
case 3: // states.MULTI_BULK_COUNT
|
|
142
143
|
if (incoming_buf[pos] === 13) { // \r
|
|
143
144
|
this.state = states.MULTI_BULK_COUNT_LF;
|
|
144
145
|
} else {
|
|
@@ -146,7 +147,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
146
147
|
}
|
|
147
148
|
pos += 1;
|
|
148
149
|
break;
|
|
149
|
-
case states.MULTI_BULK_COUNT_LF
|
|
150
|
+
case 11: // states.MULTI_BULK_COUNT_LF
|
|
150
151
|
if (incoming_buf[pos] === 10) { // \n
|
|
151
152
|
if (this.multi_bulk_length) { // nested multi-bulk
|
|
152
153
|
this.multi_bulk_nested_length = this.multi_bulk_length;
|
|
@@ -172,7 +173,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
172
173
|
}
|
|
173
174
|
pos += 1;
|
|
174
175
|
break;
|
|
175
|
-
case states.BULK_LENGTH
|
|
176
|
+
case 5: // states.BULK_LENGTH
|
|
176
177
|
if (incoming_buf[pos] === 13) { // \r
|
|
177
178
|
this.state = states.BULK_LF;
|
|
178
179
|
} else {
|
|
@@ -180,7 +181,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
180
181
|
}
|
|
181
182
|
pos += 1;
|
|
182
183
|
break;
|
|
183
|
-
case states.BULK_LF
|
|
184
|
+
case 12: // states.BULK_LF
|
|
184
185
|
if (incoming_buf[pos] === 10) { // \n
|
|
185
186
|
this.bulk_length = +this.tmp_string;
|
|
186
187
|
if (this.bulk_length === -1) {
|
|
@@ -205,7 +206,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
205
206
|
}
|
|
206
207
|
pos += 1;
|
|
207
208
|
break;
|
|
208
|
-
case states.BULK_DATA
|
|
209
|
+
case 7: // states.BULK_DATA
|
|
209
210
|
this.return_buffer[this.return_buffer.end] = incoming_buf[pos];
|
|
210
211
|
this.return_buffer.end += 1;
|
|
211
212
|
pos += 1;
|
|
@@ -223,7 +224,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
223
224
|
this.state = states.FINAL_CR;
|
|
224
225
|
}
|
|
225
226
|
break;
|
|
226
|
-
case states.FINAL_CR
|
|
227
|
+
case 9: // states.FINAL_CR
|
|
227
228
|
if (incoming_buf[pos] === 13) { // \r
|
|
228
229
|
this.state = states.FINAL_LF;
|
|
229
230
|
pos += 1;
|
|
@@ -232,7 +233,7 @@ RedisReplyParser.prototype.execute = function (incoming_buf) {
|
|
|
232
233
|
return;
|
|
233
234
|
}
|
|
234
235
|
break;
|
|
235
|
-
case states.FINAL_LF
|
|
236
|
+
case 10: // states.FINAL_LF
|
|
236
237
|
if (incoming_buf[pos] === 10) { // \n
|
|
237
238
|
this.state = states.TYPE;
|
|
238
239
|
pos += 1;
|
package/lib/queue.js
CHANGED
|
@@ -5,7 +5,7 @@ var to_array = require("./to_array");
|
|
|
5
5
|
|
|
6
6
|
function Queue() {
|
|
7
7
|
this.tail = [];
|
|
8
|
-
this.head =
|
|
8
|
+
this.head = [];
|
|
9
9
|
this.offset = 0;
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -55,4 +55,7 @@ Object.defineProperty(Queue.prototype, 'length', {
|
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
|
|
59
|
+
if(typeof module !== 'undefined' && module.exports) {
|
|
60
|
+
module.exports = Queue;
|
|
61
|
+
}
|
package/lib/util.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
// Support for very old versions of node where the module was called "sys". At some point, we should abandon this.
|
|
2
|
+
|
|
3
|
+
var util;
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
util = require("util");
|
|
7
|
+
} catch (err) {
|
|
8
|
+
util = require("sys");
|
|
6
9
|
}
|
|
10
|
+
|
|
11
|
+
module.exports = util;
|
package/mem.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var client = require("redis").createClient();
|
|
2
|
+
|
|
3
|
+
client.set("foo", "barvalskdjlksdjflkdsjflksdjdflkdsjflksdjflksdj", function (err, res) {
|
|
4
|
+
if (err) {
|
|
5
|
+
console.log("Got an error, please adapt somehow.");
|
|
6
|
+
} else {
|
|
7
|
+
console.log("Got a result: " + res);
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
client.quit();
|
package/multi_bench.js
CHANGED
|
@@ -1,134 +1,224 @@
|
|
|
1
1
|
var redis = require("./index"),
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
clients = new Array(num_clients),
|
|
2
|
+
metrics = require("metrics"),
|
|
3
|
+
num_clients = parseInt(process.argv[2], 10) || 5,
|
|
5
4
|
num_requests = 20000,
|
|
6
|
-
issued_requests = 0,
|
|
7
|
-
latency = new Array(num_requests),
|
|
8
5
|
tests = [],
|
|
9
|
-
|
|
6
|
+
versions_logged = false,
|
|
10
7
|
client_options = {
|
|
11
8
|
return_buffers: false
|
|
12
|
-
}
|
|
9
|
+
},
|
|
10
|
+
small_str, large_str, small_buf, large_buf;
|
|
13
11
|
|
|
14
12
|
redis.debug_mode = false;
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
descr: "SET",
|
|
23
|
-
command: ["set", "foo_rand000000000000", "bar"]
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
tests.push({
|
|
27
|
-
descr: "GET",
|
|
28
|
-
command: ["get", "foo_rand000000000000"]
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
tests.push({
|
|
32
|
-
descr: "INCR",
|
|
33
|
-
command: ["incr", "counter_rand000000000000"]
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
tests.push({
|
|
37
|
-
descr: "LPUSH",
|
|
38
|
-
command: ["lpush", "mylist", new Array(8).join("-")]
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
tests.push({
|
|
42
|
-
descr: "LRANGE (10 elements)",
|
|
43
|
-
command: ["lrange", "mylist", "0", "9"]
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
tests.push({
|
|
47
|
-
descr: "LRANGE (100 elements)",
|
|
48
|
-
command: ["lrange", "mylist", "0", "99"]
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
function create_clients(callback) {
|
|
52
|
-
if (active_clients === num_clients) {
|
|
53
|
-
// common case is all clients are already created
|
|
54
|
-
console.log("create_clients: all clients already created " + num_clients);
|
|
55
|
-
callback();
|
|
56
|
-
} else {
|
|
57
|
-
var client, connected = active_clients;
|
|
58
|
-
|
|
59
|
-
while (active_clients < num_clients) {
|
|
60
|
-
client = clients[active_clients++] = redis.createClient(6379, "127.0.0.1", client_options);
|
|
61
|
-
if (! parser_logged) {
|
|
62
|
-
console.log("Using reply parser " + client.reply_parser.name);
|
|
63
|
-
parser_logged = true;
|
|
64
|
-
}
|
|
65
|
-
client.on("connect", function () {
|
|
66
|
-
// Fire callback when all clients are connected
|
|
67
|
-
connected += 1;
|
|
68
|
-
if (connected === num_clients) {
|
|
69
|
-
callback();
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
// TODO - need to check for client disconnect
|
|
73
|
-
client.on("error", function (msg) {
|
|
74
|
-
console.log("Connect problem:" + msg.stack);
|
|
75
|
-
});
|
|
76
|
-
}
|
|
14
|
+
function lpad(input, len, chr) {
|
|
15
|
+
var str = input.toString();
|
|
16
|
+
chr = chr || " ";
|
|
17
|
+
|
|
18
|
+
while (str.length < len) {
|
|
19
|
+
str = chr + str;
|
|
77
20
|
}
|
|
21
|
+
return str;
|
|
78
22
|
}
|
|
79
23
|
|
|
80
|
-
function
|
|
81
|
-
var
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
24
|
+
metrics.Histogram.prototype.print_line = function () {
|
|
25
|
+
var obj = this.printObj();
|
|
26
|
+
|
|
27
|
+
return lpad(obj.min, 4) + "/" + lpad(obj.max, 4) + "/" + lpad(obj.mean.toFixed(2), 7) + "/" + lpad(obj.p95.toFixed(2), 7);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function Test(args) {
|
|
31
|
+
var self = this;
|
|
32
|
+
|
|
33
|
+
this.args = args;
|
|
34
|
+
|
|
35
|
+
this.callback = null;
|
|
36
|
+
this.clients = [];
|
|
37
|
+
this.clients_ready = 0;
|
|
38
|
+
this.commands_sent = 0;
|
|
39
|
+
this.commands_completed = 0;
|
|
40
|
+
this.max_pipeline = this.args.pipeline || num_requests;
|
|
41
|
+
this.client_options = args.client_options || client_options;
|
|
42
|
+
|
|
43
|
+
this.connect_latency = new metrics.Histogram();
|
|
44
|
+
this.ready_latency = new metrics.Histogram();
|
|
45
|
+
this.command_latency = new metrics.Histogram();
|
|
94
46
|
}
|
|
95
47
|
|
|
96
|
-
function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
48
|
+
Test.prototype.run = function (callback) {
|
|
49
|
+
var self = this, i;
|
|
50
|
+
|
|
51
|
+
this.callback = callback;
|
|
52
|
+
|
|
53
|
+
for (i = 0; i < num_clients ; i++) {
|
|
54
|
+
this.new_client(i);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
Test.prototype.new_client = function (id) {
|
|
59
|
+
var self = this, new_client;
|
|
60
|
+
|
|
61
|
+
new_client = redis.createClient(6379, "127.0.0.1", this.client_options);
|
|
62
|
+
new_client.create_time = Date.now();
|
|
63
|
+
|
|
64
|
+
new_client.on("connect", function () {
|
|
65
|
+
self.connect_latency.update(Date.now() - new_client.create_time);
|
|
66
|
+
});
|
|
101
67
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
68
|
+
new_client.on("ready", function () {
|
|
69
|
+
if (! versions_logged) {
|
|
70
|
+
console.log("Client count: " + num_clients + ", node version: " + process.versions.node + ", server version: " +
|
|
71
|
+
new_client.server_info.redis_version + ", parser: " + new_client.reply_parser.name);
|
|
72
|
+
versions_logged = true;
|
|
73
|
+
}
|
|
74
|
+
self.ready_latency.update(Date.now() - new_client.create_time);
|
|
75
|
+
self.clients_ready++;
|
|
76
|
+
if (self.clients_ready === self.clients.length) {
|
|
77
|
+
self.on_clients_ready();
|
|
106
78
|
}
|
|
107
79
|
});
|
|
108
|
-
}
|
|
109
80
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
var total_time = Date.now() - test_start;
|
|
113
|
-
var op_rate = (issued_requests / (total_time / 1000.0)).toFixed(2);
|
|
114
|
-
var i;
|
|
81
|
+
self.clients[id] = new_client;
|
|
82
|
+
};
|
|
115
83
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
for (sum = 0, i = 0; i < issued_requests; i++)
|
|
120
|
-
sum += latency[i];
|
|
121
|
-
avg = (sum / issued_requests).toFixed(3);
|
|
84
|
+
Test.prototype.on_clients_ready = function () {
|
|
85
|
+
process.stdout.write(lpad(this.args.descr, 13) + ", " + lpad(this.args.pipeline, 5) + "/" + this.clients_ready + " ");
|
|
86
|
+
this.test_start = Date.now();
|
|
122
87
|
|
|
123
|
-
|
|
88
|
+
this.fill_pipeline();
|
|
89
|
+
};
|
|
124
90
|
|
|
125
|
-
|
|
126
|
-
|
|
91
|
+
Test.prototype.fill_pipeline = function () {
|
|
92
|
+
var pipeline = this.commands_sent - this.commands_completed;
|
|
93
|
+
|
|
94
|
+
while (this.commands_sent < num_requests && pipeline < this.max_pipeline) {
|
|
95
|
+
this.commands_sent++;
|
|
96
|
+
pipeline++;
|
|
97
|
+
this.send_next();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (this.commands_completed === num_requests) {
|
|
101
|
+
this.print_stats();
|
|
102
|
+
this.stop_clients();
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
Test.prototype.stop_clients = function () {
|
|
107
|
+
var self = this;
|
|
108
|
+
|
|
109
|
+
this.clients.forEach(function (client, pos) {
|
|
110
|
+
if (pos === self.clients.length - 1) {
|
|
111
|
+
client.quit(function (err, res) {
|
|
112
|
+
self.callback();
|
|
113
|
+
});
|
|
114
|
+
} else {
|
|
115
|
+
client.quit();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
Test.prototype.send_next = function () {
|
|
121
|
+
var self = this,
|
|
122
|
+
cur_client = this.commands_sent % this.clients.length,
|
|
123
|
+
command_num = this.commands_sent,
|
|
124
|
+
start = Date.now();
|
|
125
|
+
|
|
126
|
+
this.clients[cur_client][this.args.command](this.args.args, function (err, res) {
|
|
127
|
+
if (err) {
|
|
128
|
+
throw err;
|
|
129
|
+
}
|
|
130
|
+
self.commands_completed++;
|
|
131
|
+
self.command_latency.update(Date.now() - start);
|
|
132
|
+
self.fill_pipeline();
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
Test.prototype.print_stats = function () {
|
|
137
|
+
var duration = Date.now() - this.test_start;
|
|
138
|
+
|
|
139
|
+
console.log("min/max/avg/p95: " + this.command_latency.print_line() + " " + lpad(duration, 6) + "ms total, " +
|
|
140
|
+
lpad((num_requests / (duration / 1000)).toFixed(2), 8) + " ops/sec");
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
small_str = "1234";
|
|
144
|
+
small_buf = new Buffer(small_str);
|
|
145
|
+
large_str = (new Array(4097).join("-"));
|
|
146
|
+
large_buf = new Buffer(large_str);
|
|
147
|
+
|
|
148
|
+
tests.push(new Test({descr: "PING", command: "ping", args: [], pipeline: 1}));
|
|
149
|
+
tests.push(new Test({descr: "PING", command: "ping", args: [], pipeline: 50}));
|
|
150
|
+
tests.push(new Test({descr: "PING", command: "ping", args: [], pipeline: 200}));
|
|
151
|
+
tests.push(new Test({descr: "PING", command: "ping", args: [], pipeline: 20000}));
|
|
152
|
+
|
|
153
|
+
tests.push(new Test({descr: "SET small str", command: "set", args: ["foo_rand000000000000", small_str], pipeline: 1}));
|
|
154
|
+
tests.push(new Test({descr: "SET small str", command: "set", args: ["foo_rand000000000000", small_str], pipeline: 50}));
|
|
155
|
+
tests.push(new Test({descr: "SET small str", command: "set", args: ["foo_rand000000000000", small_str], pipeline: 200}));
|
|
156
|
+
tests.push(new Test({descr: "SET small str", command: "set", args: ["foo_rand000000000000", small_str], pipeline: 20000}));
|
|
157
|
+
|
|
158
|
+
tests.push(new Test({descr: "SET small buf", command: "set", args: ["foo_rand000000000000", small_buf], pipeline: 1}));
|
|
159
|
+
tests.push(new Test({descr: "SET small buf", command: "set", args: ["foo_rand000000000000", small_buf], pipeline: 50}));
|
|
160
|
+
tests.push(new Test({descr: "SET small buf", command: "set", args: ["foo_rand000000000000", small_buf], pipeline: 200}));
|
|
161
|
+
tests.push(new Test({descr: "SET small buf", command: "set", args: ["foo_rand000000000000", small_buf], pipeline: 20000}));
|
|
162
|
+
|
|
163
|
+
tests.push(new Test({descr: "GET small str", command: "get", args: ["foo_rand000000000000"], pipeline: 1}));
|
|
164
|
+
tests.push(new Test({descr: "GET small str", command: "get", args: ["foo_rand000000000000"], pipeline: 50}));
|
|
165
|
+
tests.push(new Test({descr: "GET small str", command: "get", args: ["foo_rand000000000000"], pipeline: 200}));
|
|
166
|
+
tests.push(new Test({descr: "GET small str", command: "get", args: ["foo_rand000000000000"], pipeline: 20000}));
|
|
167
|
+
|
|
168
|
+
tests.push(new Test({descr: "GET small buf", command: "get", args: ["foo_rand000000000000"], pipeline: 1, client_opts: { return_buffers: true} }));
|
|
169
|
+
tests.push(new Test({descr: "GET small buf", command: "get", args: ["foo_rand000000000000"], pipeline: 50, client_opts: { return_buffers: true} }));
|
|
170
|
+
tests.push(new Test({descr: "GET small buf", command: "get", args: ["foo_rand000000000000"], pipeline: 200, client_opts: { return_buffers: true} }));
|
|
171
|
+
tests.push(new Test({descr: "GET small buf", command: "get", args: ["foo_rand000000000000"], pipeline: 20000, client_opts: { return_buffers: true} }));
|
|
172
|
+
|
|
173
|
+
tests.push(new Test({descr: "SET large str", command: "set", args: ["foo_rand000000000001", large_str], pipeline: 1}));
|
|
174
|
+
tests.push(new Test({descr: "SET large str", command: "set", args: ["foo_rand000000000001", large_str], pipeline: 50}));
|
|
175
|
+
tests.push(new Test({descr: "SET large str", command: "set", args: ["foo_rand000000000001", large_str], pipeline: 200}));
|
|
176
|
+
tests.push(new Test({descr: "SET large str", command: "set", args: ["foo_rand000000000001", large_str], pipeline: 20000}));
|
|
177
|
+
|
|
178
|
+
tests.push(new Test({descr: "SET large buf", command: "set", args: ["foo_rand000000000001", large_buf], pipeline: 1}));
|
|
179
|
+
tests.push(new Test({descr: "SET large buf", command: "set", args: ["foo_rand000000000001", large_buf], pipeline: 50}));
|
|
180
|
+
tests.push(new Test({descr: "SET large buf", command: "set", args: ["foo_rand000000000001", large_buf], pipeline: 200}));
|
|
181
|
+
tests.push(new Test({descr: "SET large buf", command: "set", args: ["foo_rand000000000001", large_buf], pipeline: 20000}));
|
|
182
|
+
|
|
183
|
+
tests.push(new Test({descr: "GET large str", command: "get", args: ["foo_rand000000000001"], pipeline: 1}));
|
|
184
|
+
tests.push(new Test({descr: "GET large str", command: "get", args: ["foo_rand000000000001"], pipeline: 50}));
|
|
185
|
+
tests.push(new Test({descr: "GET large str", command: "get", args: ["foo_rand000000000001"], pipeline: 200}));
|
|
186
|
+
tests.push(new Test({descr: "GET large str", command: "get", args: ["foo_rand000000000001"], pipeline: 20000}));
|
|
187
|
+
|
|
188
|
+
tests.push(new Test({descr: "GET large buf", command: "get", args: ["foo_rand000000000001"], pipeline: 1, client_opts: { return_buffers: true} }));
|
|
189
|
+
tests.push(new Test({descr: "GET large buf", command: "get", args: ["foo_rand000000000001"], pipeline: 50, client_opts: { return_buffers: true} }));
|
|
190
|
+
tests.push(new Test({descr: "GET large buf", command: "get", args: ["foo_rand000000000001"], pipeline: 200, client_opts: { return_buffers: true} }));
|
|
191
|
+
tests.push(new Test({descr: "GET large buf", command: "get", args: ["foo_rand000000000001"], pipeline: 20000, client_opts: { return_buffers: true} }));
|
|
192
|
+
|
|
193
|
+
tests.push(new Test({descr: "INCR", command: "incr", args: ["counter_rand000000000000"], pipeline: 1}));
|
|
194
|
+
tests.push(new Test({descr: "INCR", command: "incr", args: ["counter_rand000000000000"], pipeline: 50}));
|
|
195
|
+
tests.push(new Test({descr: "INCR", command: "incr", args: ["counter_rand000000000000"], pipeline: 200}));
|
|
196
|
+
tests.push(new Test({descr: "INCR", command: "incr", args: ["counter_rand000000000000"], pipeline: 20000}));
|
|
197
|
+
|
|
198
|
+
tests.push(new Test({descr: "LPUSH", command: "lpush", args: ["mylist", small_str], pipeline: 1}));
|
|
199
|
+
tests.push(new Test({descr: "LPUSH", command: "lpush", args: ["mylist", small_str], pipeline: 50}));
|
|
200
|
+
tests.push(new Test({descr: "LPUSH", command: "lpush", args: ["mylist", small_str], pipeline: 200}));
|
|
201
|
+
tests.push(new Test({descr: "LPUSH", command: "lpush", args: ["mylist", small_str], pipeline: 20000}));
|
|
202
|
+
|
|
203
|
+
tests.push(new Test({descr: "LRANGE 10", command: "lrange", args: ["mylist", "0", "9"], pipeline: 1}));
|
|
204
|
+
tests.push(new Test({descr: "LRANGE 10", command: "lrange", args: ["mylist", "0", "9"], pipeline: 50}));
|
|
205
|
+
tests.push(new Test({descr: "LRANGE 10", command: "lrange", args: ["mylist", "0", "9"], pipeline: 200}));
|
|
206
|
+
tests.push(new Test({descr: "LRANGE 10", command: "lrange", args: ["mylist", "0", "9"], pipeline: 20000}));
|
|
207
|
+
|
|
208
|
+
tests.push(new Test({descr: "LRANGE 100", command: "lrange", args: ["mylist", "0", "99"], pipeline: 1}));
|
|
209
|
+
tests.push(new Test({descr: "LRANGE 100", command: "lrange", args: ["mylist", "0", "99"], pipeline: 50}));
|
|
210
|
+
tests.push(new Test({descr: "LRANGE 100", command: "lrange", args: ["mylist", "0", "99"], pipeline: 200}));
|
|
211
|
+
tests.push(new Test({descr: "LRANGE 100", command: "lrange", args: ["mylist", "0", "99"], pipeline: 20000}));
|
|
127
212
|
|
|
128
213
|
function next() {
|
|
129
214
|
var test = tests.shift();
|
|
130
215
|
if (test) {
|
|
131
|
-
|
|
216
|
+
test.run(function () {
|
|
217
|
+
next();
|
|
218
|
+
});
|
|
219
|
+
} else {
|
|
220
|
+
console.log("End of tests.");
|
|
221
|
+
process.exit(0);
|
|
132
222
|
}
|
|
133
223
|
}
|
|
134
224
|
|
package/package.json
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
{ "name" : "redis",
|
|
2
|
-
"version" : "0.
|
|
2
|
+
"version" : "0.7.3",
|
|
3
3
|
"description" : "Redis client library",
|
|
4
4
|
"author": "Matt Ranney <mjr@ranney.com>",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"Tim-Smart",
|
|
8
|
-
"TJ Holowaychuk",
|
|
9
|
-
"Orion Henry",
|
|
10
|
-
"Hank Sims",
|
|
11
|
-
"Aivo Paas",
|
|
12
|
-
"Paul Carey",
|
|
13
|
-
"Pieter Noordhuis",
|
|
14
|
-
"Andy Ray",
|
|
15
|
-
"Vladimir Dronnikov",
|
|
16
|
-
"Dave Hoover"
|
|
5
|
+
"maintainers": [
|
|
6
|
+
"David Trejo <david.daniel.trejo@gmail.com> (http://dtrejo.com/)"
|
|
17
7
|
],
|
|
18
8
|
"main": "./index.js",
|
|
19
9
|
"scripts": {
|
|
20
10
|
"test": "node ./test.js"
|
|
21
11
|
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"metrics": ">=0.1.5"
|
|
14
|
+
},
|
|
22
15
|
"repository": {
|
|
23
16
|
"type": "git",
|
|
24
17
|
"url": "git://github.com/mranney/node_redis.git"
|