Skip to content

Commit 79fc400

Browse files
committed
Merge pull request #1074 from NodeRedis/v.2.6.0-proposal
v.2.6.0-proposal
2 parents bfdbf16 + a41cfa9 commit 79fc400

25 files changed

+706
-508
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ node_js:
1212
- "0.10"
1313
- "0.12"
1414
- "4"
15-
- "5"
15+
- "6"
1616
after_success: npm run coveralls

README.md

+68-48
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ __Tip:__ If the Redis server runs on the same machine as the client consider usi
182182
| port | 6379 | Port of the Redis server |
183183
| path | null | The UNIX socket string of the Redis server |
184184
| url | null | The URL of the Redis server. Format: `[redis:]//[[user][:password@]][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]` (More info avaliable at [IANA](http://www.iana.org/assignments/uri-schemes/prov/redis)). |
185-
| parser | hiredis | If hiredis is not installed, automatic fallback to the built-in javascript parser |
186-
| string_numbers | null | Set to `true`, `node_redis` will return Redis number values as Strings instead of javascript Numbers. Useful if you need to handle big numbers (above `Number.MAX_SAFE_INTEGER === 2^53`). Hiredis is incapable of this behavior, so setting this option to `true` will result in the built-in javascript parser being used no matter the value of the `parser` option. |
185+
| parser | javascript | __Deprecated__ Use either the built-in JS parser [`javascript`]() or the native [`hiredis`]() parser. __Note__ `node_redis` < 2.6 uses hiredis as default if installed. This changed in v.2.6.0. |
186+
| string_numbers | null | Set to `true`, `node_redis` will return Redis number values as Strings instead of javascript Numbers. Useful if you need to handle big numbers (above `Number.MAX_SAFE_INTEGER === 2^53`). Hiredis is incapable of this behavior, so setting this option to `true` will result in the built-in javascript parser being used no matter the value of the `parser` option. |
187187
| return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. |
188188
| detect_buffers | false | If set to `true`, then replies will be sent to callbacks as Buffers. This option lets you switch between Buffers and Strings on a per-command basis, whereas `return_buffers` applies to every command on a client. __Note__: This doesn't work properly with the pubsub mode. A subscriber has to either always return Strings or Buffers. |
189189
| socket_keepalive | true | If set to `true`, the keep-alive functionality is enabled on the underlying socket. |
@@ -712,60 +712,80 @@ client.zadd(args, function (err, response) {
712712
## Performance
713713

714714
Much effort has been spent to make `node_redis` as fast as possible for common
715-
operations. As pipelining happens naturally from shared connections, overall
716-
efficiency goes up.
717-
718-
Here are results of `multi_bench.js` which is similar to `redis-benchmark` from the Redis distribution.
719-
720-
hiredis parser (Lenovo T450s i7-5600U):
715+
operations.
721716

722717
```
723-
Client count: 1, node version: 4.2.2, server version: 3.0.3, parser: hiredis
724-
PING, 1/1 min/max/avg: 0/ 2/ 0.02/ 2501ms total, 47503.80 ops/sec
725-
PING, batch 50/1 min/max/avg: 0/ 2/ 0.09/ 2501ms total, 529668.13 ops/sec
726-
SET 4B str, 1/1 min/max/avg: 0/ 2/ 0.02/ 2501ms total, 41900.04 ops/sec
727-
SET 4B str, batch 50/1 min/max/avg: 0/ 2/ 0.14/ 2501ms total, 354658.14 ops/sec
728-
SET 4B buf, 1/1 min/max/avg: 0/ 4/ 0.04/ 2501ms total, 23499.00 ops/sec
729-
SET 4B buf, batch 50/1 min/max/avg: 0/ 2/ 0.31/ 2501ms total, 159836.07 ops/sec
730-
GET 4B str, 1/1 min/max/avg: 0/ 4/ 0.02/ 2501ms total, 43489.80 ops/sec
731-
GET 4B str, batch 50/1 min/max/avg: 0/ 2/ 0.11/ 2501ms total, 444202.32 ops/sec
732-
GET 4B buf, 1/1 min/max/avg: 0/ 3/ 0.02/ 2501ms total, 38561.38 ops/sec
733-
GET 4B buf, batch 50/1 min/max/avg: 0/ 2/ 0.11/ 2501ms total, 452139.14 ops/sec
734-
SET 4KiB str, 1/1 min/max/avg: 0/ 2/ 0.03/ 2501ms total, 32990.80 ops/sec
735-
SET 4KiB str, batch 50/1 min/max/avg: 0/ 2/ 0.34/ 2501ms total, 146161.54 ops/sec
736-
SET 4KiB buf, 1/1 min/max/avg: 0/ 1/ 0.04/ 2501ms total, 23294.28 ops/sec
737-
SET 4KiB buf, batch 50/1 min/max/avg: 0/ 2/ 0.36/ 2501ms total, 137584.97 ops/sec
738-
GET 4KiB str, 1/1 min/max/avg: 0/ 2/ 0.03/ 2501ms total, 36350.66 ops/sec
739-
GET 4KiB str, batch 50/1 min/max/avg: 0/ 2/ 0.32/ 2501ms total, 155157.94 ops/sec
740-
GET 4KiB buf, 1/1 min/max/avg: 0/ 4/ 0.02/ 2501ms total, 39776.49 ops/sec
741-
GET 4KiB buf, batch 50/1 min/max/avg: 0/ 2/ 0.32/ 2501ms total, 155457.82 ops/sec
742-
INCR, 1/1 min/max/avg: 0/ 3/ 0.02/ 2501ms total, 43972.41 ops/sec
743-
INCR, batch 50/1 min/max/avg: 0/ 1/ 0.12/ 2501ms total, 425809.68 ops/sec
744-
LPUSH, 1/1 min/max/avg: 0/ 2/ 0.02/ 2501ms total, 38998.40 ops/sec
745-
LPUSH, batch 50/1 min/max/avg: 0/ 4/ 0.14/ 2501ms total, 365013.99 ops/sec
746-
LRANGE 10, 1/1 min/max/avg: 0/ 2/ 0.03/ 2501ms total, 31879.25 ops/sec
747-
LRANGE 10, batch 50/1 min/max/avg: 0/ 1/ 0.32/ 2501ms total, 153698.52 ops/sec
748-
LRANGE 100, 1/1 min/max/avg: 0/ 4/ 0.06/ 2501ms total, 16676.13 ops/sec
749-
LRANGE 100, batch 50/1 min/max/avg: 1/ 6/ 2.03/ 2502ms total, 24520.38 ops/sec
750-
SET 4MiB str, 1/1 min/max/avg: 1/ 6/ 2.11/ 2502ms total, 472.82 ops/sec
751-
SET 4MiB str, batch 20/1 min/max/avg: 85/ 112/ 94.93/ 2563ms total, 210.69 ops/sec
752-
SET 4MiB buf, 1/1 min/max/avg: 1/ 8/ 2.02/ 2502ms total, 490.01 ops/sec
753-
SET 4MiB buf, batch 20/1 min/max/avg: 37/ 52/ 39.48/ 2528ms total, 506.33 ops/sec
754-
GET 4MiB str, 1/1 min/max/avg: 3/ 13/ 5.26/ 2504ms total, 190.10 ops/sec
755-
GET 4MiB str, batch 20/1 min/max/avg: 70/ 106/ 89.36/ 2503ms total, 223.73 ops/sec
756-
GET 4MiB buf, 1/1 min/max/avg: 3/ 11/ 5.04/ 2502ms total, 198.24 ops/sec
757-
GET 4MiB buf, batch 20/1 min/max/avg: 70/ 105/ 88.07/ 2554ms total, 227.09 ops/sec
718+
Lenovo T450s, i7-5600U and 12gb memory
719+
clients: 1, NodeJS: 6.2.0, Redis: 3.2.0, parser: javascript, connected by: tcp
720+
PING, 1/1 avg/max: 0.02/ 5.26 2501ms total, 46916 ops/sec
721+
PING, batch 50/1 avg/max: 0.06/ 4.35 2501ms total, 755178 ops/sec
722+
SET 4B str, 1/1 avg/max: 0.02/ 4.75 2501ms total, 40856 ops/sec
723+
SET 4B str, batch 50/1 avg/max: 0.11/ 1.51 2501ms total, 432727 ops/sec
724+
SET 4B buf, 1/1 avg/max: 0.05/ 2.76 2501ms total, 20659 ops/sec
725+
SET 4B buf, batch 50/1 avg/max: 0.25/ 1.76 2501ms total, 194962 ops/sec
726+
GET 4B str, 1/1 avg/max: 0.02/ 1.55 2501ms total, 45156 ops/sec
727+
GET 4B str, batch 50/1 avg/max: 0.09/ 3.15 2501ms total, 524110 ops/sec
728+
GET 4B buf, 1/1 avg/max: 0.02/ 3.07 2501ms total, 44563 ops/sec
729+
GET 4B buf, batch 50/1 avg/max: 0.10/ 3.18 2501ms total, 473171 ops/sec
730+
SET 4KiB str, 1/1 avg/max: 0.03/ 1.54 2501ms total, 32627 ops/sec
731+
SET 4KiB str, batch 50/1 avg/max: 0.34/ 1.89 2501ms total, 146861 ops/sec
732+
SET 4KiB buf, 1/1 avg/max: 0.05/ 2.85 2501ms total, 20688 ops/sec
733+
SET 4KiB buf, batch 50/1 avg/max: 0.36/ 1.83 2501ms total, 138165 ops/sec
734+
GET 4KiB str, 1/1 avg/max: 0.02/ 1.37 2501ms total, 39389 ops/sec
735+
GET 4KiB str, batch 50/1 avg/max: 0.24/ 1.81 2501ms total, 208157 ops/sec
736+
GET 4KiB buf, 1/1 avg/max: 0.02/ 2.63 2501ms total, 39918 ops/sec
737+
GET 4KiB buf, batch 50/1 avg/max: 0.31/ 8.56 2501ms total, 161575 ops/sec
738+
INCR, 1/1 avg/max: 0.02/ 4.69 2501ms total, 45685 ops/sec
739+
INCR, batch 50/1 avg/max: 0.09/ 3.06 2501ms total, 539964 ops/sec
740+
LPUSH, 1/1 avg/max: 0.02/ 3.04 2501ms total, 41253 ops/sec
741+
LPUSH, batch 50/1 avg/max: 0.12/ 1.94 2501ms total, 425090 ops/sec
742+
LRANGE 10, 1/1 avg/max: 0.02/ 2.28 2501ms total, 39850 ops/sec
743+
LRANGE 10, batch 50/1 avg/max: 0.25/ 1.85 2501ms total, 194302 ops/sec
744+
LRANGE 100, 1/1 avg/max: 0.05/ 2.93 2501ms total, 21026 ops/sec
745+
LRANGE 100, batch 50/1 avg/max: 1.52/ 2.89 2501ms total, 32767 ops/sec
746+
SET 4MiB str, 1/1 avg/max: 5.16/ 15.55 2502ms total, 193 ops/sec
747+
SET 4MiB str, batch 20/1 avg/max: 89.73/ 99.96 2513ms total, 223 ops/sec
748+
SET 4MiB buf, 1/1 avg/max: 2.23/ 8.35 2501ms total, 446 ops/sec
749+
SET 4MiB buf, batch 20/1 avg/max: 41.47/ 50.91 2530ms total, 482 ops/sec
750+
GET 4MiB str, 1/1 avg/max: 2.79/ 10.91 2502ms total, 358 ops/sec
751+
GET 4MiB str, batch 20/1 avg/max: 101.61/118.11 2541ms total, 197 ops/sec
752+
GET 4MiB buf, 1/1 avg/max: 2.32/ 14.93 2502ms total, 430 ops/sec
753+
GET 4MiB buf, batch 20/1 avg/max: 65.01/ 84.72 2536ms total, 308 ops/sec
758754
```
759755

760-
The hiredis and js parser should most of the time be on the same level. But if you use Redis for big SUNION/SINTER/LRANGE/ZRANGE hiredis is faster.
761-
Therefor the hiredis parser is the default used in node_redis. To use `hiredis`, do:
762-
763-
npm install hiredis redis
764-
765756
## Debugging
766757

767758
To get debug output run your `node_redis` application with `NODE_DEBUG=redis`.
768759

760+
This is also going to result in good stack traces opposed to useless ones otherwise for any async operation.
761+
If you only want to have good stack traces but not the debug output run your application in development mode instead (`NODE_ENV=development`).
762+
763+
Good stack traces are only activated in development and debug mode as this results in a significant performance penalty.
764+
765+
___Comparison___:
766+
Useless stack trace:
767+
```
768+
ReplyError: ERR wrong number of arguments for 'set' command
769+
at parseError (/home/ruben/repos/redis/node_modules/redis-parser/lib/parser.js:158:12)
770+
at parseType (/home/ruben/repos/redis/node_modules/redis-parser/lib/parser.js:219:14)
771+
```
772+
Good stack trace:
773+
```
774+
ReplyError: ERR wrong number of arguments for 'set' command
775+
at new Command (/home/ruben/repos/redis/lib/command.js:9:902)
776+
at RedisClient.set (/home/ruben/repos/redis/lib/commands.js:9:3238)
777+
at Context.<anonymous> (/home/ruben/repos/redis/test/good_stacks.spec.js:20:20)
778+
at callFnAsync (/home/ruben/repos/redis/node_modules/mocha/lib/runnable.js:349:8)
779+
at Test.Runnable.run (/home/ruben/repos/redis/node_modules/mocha/lib/runnable.js:301:7)
780+
at Runner.runTest (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:422:10)
781+
at /home/ruben/repos/redis/node_modules/mocha/lib/runner.js:528:12
782+
at next (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:342:14)
783+
at /home/ruben/repos/redis/node_modules/mocha/lib/runner.js:352:7
784+
at next (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:284:14)
785+
at Immediate._onImmediate (/home/ruben/repos/redis/node_modules/mocha/lib/runner.js:320:5)
786+
at processImmediate [as _immediateCallback] (timers.js:383:17)
787+
```
788+
769789
## How to Contribute
770790
- Open a pull request or an issue about what you want to implement / change. We're glad for any help!
771791
- Please be aware that we'll only accept fully tested code.

appveyor.yml

+3-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ environment:
66
- nodejs_version: "0.10"
77
- nodejs_version: "0.12"
88
- nodejs_version: "4"
9-
- nodejs_version: "5"
9+
- nodejs_version: "6"
1010

1111
pull_requests:
1212
do_not_increment_build_number: true
@@ -21,11 +21,10 @@ install:
2121
- redis-64\tools\redis-server.exe --service-install
2222
- redis-64\tools\redis-server.exe --service-start
2323
- '@ECHO Redis Started'
24-
# Get the latest stable version of Node 0.STABLE.latest
24+
# Get the required Node version
2525
- ps: Install-Product node $env:nodejs_version
26-
# Typical npm stuff. Use msvs 2013 for the hiredis parser
26+
# Typical npm stuff
2727
- npm install
28-
- npm install hiredis --msvs_version=2013
2928

3029
# Post-install test scripts.
3130
test_script:

benchmarks/multi_bench.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var run_time = returnArg('time', 2500); // ms
2626
var pipeline = returnArg('pipeline', 1); // number of concurrent commands
2727
var versions_logged = false;
2828
var client_options = {
29-
parser: returnArg('parser', 'hiredis'),
29+
parser: returnArg('parser', 'javascript'),
3030
path: returnArg('socket') // '/tmp/redis.sock'
3131
};
3232
var small_str, large_str, small_buf, large_buf, very_large_str, very_large_buf;
@@ -231,8 +231,8 @@ tests.push(new Test({descr: 'SET 4B buf', command: 'set', args: ['foo_rand000000
231231
tests.push(new Test({descr: 'GET 4B str', command: 'get', args: ['foo_rand000000000000']}));
232232
tests.push(new Test({descr: 'GET 4B str', command: 'get', args: ['foo_rand000000000000'], batch: 50}));
233233

234-
tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['foo_rand000000000000'], client_opts: { return_buffers: true} }));
235-
tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['foo_rand000000000000'], batch: 50, client_opts: { return_buffers: true} }));
234+
tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['foo_rand000000000000'], client_options: { return_buffers: true} }));
235+
tests.push(new Test({descr: 'GET 4B buf', command: 'get', args: ['foo_rand000000000000'], batch: 50, client_options: { return_buffers: true} }));
236236

237237
tests.push(new Test({descr: 'SET 4KiB str', command: 'set', args: ['foo_rand000000000001', large_str]}));
238238
tests.push(new Test({descr: 'SET 4KiB str', command: 'set', args: ['foo_rand000000000001', large_str], batch: 50}));
@@ -243,8 +243,8 @@ tests.push(new Test({descr: 'SET 4KiB buf', command: 'set', args: ['foo_rand0000
243243
tests.push(new Test({descr: 'GET 4KiB str', command: 'get', args: ['foo_rand000000000001']}));
244244
tests.push(new Test({descr: 'GET 4KiB str', command: 'get', args: ['foo_rand000000000001'], batch: 50}));
245245

246-
tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['foo_rand000000000001'], client_opts: { return_buffers: true} }));
247-
tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['foo_rand000000000001'], batch: 50, client_opts: { return_buffers: true} }));
246+
tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['foo_rand000000000001'], client_options: { return_buffers: true} }));
247+
tests.push(new Test({descr: 'GET 4KiB buf', command: 'get', args: ['foo_rand000000000001'], batch: 50, client_options: { return_buffers: true} }));
248248

249249
tests.push(new Test({descr: 'INCR', command: 'incr', args: ['counter_rand000000000000']}));
250250
tests.push(new Test({descr: 'INCR', command: 'incr', args: ['counter_rand000000000000'], batch: 50}));
@@ -267,8 +267,8 @@ tests.push(new Test({descr: 'SET 4MiB buf', command: 'set', args: ['foo_rand0000
267267
tests.push(new Test({descr: 'GET 4MiB str', command: 'get', args: ['foo_rand000000000002']}));
268268
tests.push(new Test({descr: 'GET 4MiB str', command: 'get', args: ['foo_rand000000000002'], batch: 20}));
269269

270-
tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['foo_rand000000000002'], client_opts: { return_buffers: true} }));
271-
tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['foo_rand000000000002'], batch: 20, client_opts: { return_buffers: true} }));
270+
tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['foo_rand000000000002'], client_options: { return_buffers: true} }));
271+
tests.push(new Test({descr: 'GET 4MiB buf', command: 'get', args: ['foo_rand000000000002'], batch: 20, client_options: { return_buffers: true} }));
272272

273273
function next () {
274274
var test = tests.shift();

changelog.md

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,37 @@
11
Changelog
22
=========
33

4+
## v.2.6.0 - 25 Mai, 2016
5+
6+
In addition to the pre-releases the following changes exist in v.2.6.0:
7+
8+
Features
9+
10+
- Updated [redis-parser](https://github.com/NodeRedis/redis-parser) dependency ([changelog](https://github.com/NodeRedis/redis-parser/releases/tag/v.2.0.0))
11+
- The JS parser is from now on the new default as it is a lot faster than the hiredis parser
12+
- This is no BC as there is no changed behavior for the user at all but just a performance improvement. Explicitly requireing the Hiredis parser is still possible.
13+
- Added name property to all Redis functions (Node.js >= 4.0)
14+
- Improved stack traces in development and debug mode
15+
16+
Bugfixes
17+
18+
- Reverted support for `__proto__` (v.2.6.0-2) to prevent and breaking change
19+
20+
Deprecations
21+
22+
- The `parser` option is deprecated and should be removed. The built-in Javascript parser is a lot faster than the hiredis parser and has more features
23+
424
## v.2.6.0-2 - 29 Apr, 2016
525

626
Features
727

8-
- Added support for the new `CLIENT REPLY ON|OFF|SKIP` command (Redis v.3.2)
28+
- Added support for the new [CLIENT REPLY ON|OFF|SKIP](http://redis.io/commands/client-reply) command (Redis v.3.2)
929
- Added support for camelCase
1030
- The Node.js landscape default is to use camelCase. node_redis is a bit out of the box here
1131
but from now on it is possible to use both, just as you prefer!
1232
- If there's any documented variable missing as camelCased, please open a issue for it
1333
- Improve error handling significantly
1434
- Only emit an error if the error has not already been handled in a callback
15-
- Emit an error if a command would otherwise silently fail (no callback present)
1635
- Improved unspecific error messages e.g. "Connection gone from end / close event"
1736
- Added `args` to command errors to improve identification of the error
1837
- Added origin to errors if there's e.g. a connection error

0 commit comments

Comments
 (0)