From 1ef099c790e6fdedc0c2add94badff0f2bfc830e Mon Sep 17 00:00:00 2001
From: Liran
Date: Tue, 7 Nov 2017 09:36:21 +0200
Subject: [PATCH 01/96] Native Promises with util.promisify
explain how to promisify to native promises (instead of bluebird) with node's v8 util.promisify.
---
README.md | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 088f1be982..90cde13997 100644
--- a/README.md
+++ b/README.md
@@ -57,11 +57,27 @@ landscape.
### Promises
+#### Native Promises
+If you are using node v8 or higher, you can promisify node_redis with [util.promisify](https://nodejs.org/api/util.html#util_util_promisify_original) as in:
+```js
+const {promisify} = require('util');
+const getAsync = promisify(client.get).bind(client);
+```
+now *getAsync* is a promisified version of *client.get*:
+```js
+// We expect a value 'foo': 'bar' to be present
+// So instead of writing client.get('foo', cb); you have to write:
+return getAsync('foo').then(function(res) {
+ console.log(res); // => 'bar'
+});
+```
+
+#### Bluebird Promises
You can also use node_redis with promises by promisifying node_redis with
[bluebird](https://github.com/petkaantonov/bluebird) as in:
```js
-var redis = require('redis');
+const redis = require('redis');
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
```
From 80f6960fb57548cebc2bfc670f594a003906036a Mon Sep 17 00:00:00 2001
From: Liran
Date: Wed, 8 Nov 2017 10:51:15 +0200
Subject: [PATCH 02/96] add async await example
---
README.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/README.md b/README.md
index 90cde13997..4490f33654 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,12 @@ now *getAsync* is a promisified version of *client.get*:
return getAsync('foo').then(function(res) {
console.log(res); // => 'bar'
});
+
+// or using [async await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
+async myFunc() {
+ const res = await getAsync('foo');
+ console.log(res);
+}
```
#### Bluebird Promises
From 2a586e35b68b3ea9459abb0acaaca2cadfc78d4a Mon Sep 17 00:00:00 2001
From: Liran
Date: Wed, 8 Nov 2017 10:52:53 +0200
Subject: [PATCH 03/96] comment with reference out of code block
---
README.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 4490f33654..c0effcdf7c 100644
--- a/README.md
+++ b/README.md
@@ -70,8 +70,10 @@ now *getAsync* is a promisified version of *client.get*:
return getAsync('foo').then(function(res) {
console.log(res); // => 'bar'
});
+```
-// or using [async await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
+or using [async await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function):
+```js
async myFunc() {
const res = await getAsync('foo');
console.log(res);
From 5d6e471d0c14df39974000427719c5d85fa4f21f Mon Sep 17 00:00:00 2001
From: calebboyd
Date: Fri, 27 Oct 2017 16:32:33 -0500
Subject: [PATCH 04/96] feat: add support for rediss protocol in url
---
README.md | 2 +-
lib/createClient.js | 6 +++++-
test/tls.spec.js | 23 +++++++++++++++++++++++
3 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index c0effcdf7c..1ec63dacdd 100644
--- a/README.md
+++ b/README.md
@@ -240,7 +240,7 @@ using unix sockets if possible to increase throughput.
| host | 127.0.0.1 | IP address of the Redis server |
| port | 6379 | Port of the Redis server |
| path | null | The UNIX socket string of the Redis server |
-| 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)). |
+| url | null | The URL of the Redis server. Format: `[redis:][rediss:]//[[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)). |
| 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. |
| 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. |
| return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. |
diff --git a/lib/createClient.js b/lib/createClient.js
index 2f3b09fdb3..8c3a8508a2 100644
--- a/lib/createClient.js
+++ b/lib/createClient.js
@@ -32,7 +32,11 @@ module.exports = function createClient (port_arg, host_arg, options) {
options.password = parsed.auth.split(':')[1];
}
if (parsed.protocol && parsed.protocol !== 'redis:') {
- console.warn('node_redis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!');
+ if (parsed.protocol === 'rediss:') {
+ options.tls = options.tls || {};
+ } else {
+ console.warn('node_redis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!');
+ }
}
if (parsed.pathname && parsed.pathname !== '/') {
options.db = parsed.pathname.substr(1);
diff --git a/test/tls.spec.js b/test/tls.spec.js
index d977ee7d9a..6a7e021e33 100644
--- a/test/tls.spec.js
+++ b/test/tls.spec.js
@@ -108,6 +108,29 @@ describe('TLS connection tests', function () {
client.get('foo', helper.isString('bar', done));
});
+ describe('using rediss as url protocol', function (done) {
+ var tls = require('tls')
+ var tlsConnect = tls.connect
+ beforeEach(function () {
+ tls.connect = function (options) {
+ options = utils.clone(options)
+ options.ca = tls_options.ca;
+ return tlsConnect.call(tls, options);
+ }
+ })
+ afterEach(function () {
+ tls.connect = tlsConnect;
+ })
+ it('connect with tls when rediss is used as the protocol', function (done) {
+ if (skip) this.skip();
+ client = redis.createClient('rediss://localhost:' + tls_port);
+ // verify connection is using TCP, not UNIX socket
+ assert(client.stream.encrypted);
+ client.set('foo', 'bar');
+ client.get('foo', helper.isString('bar', done));
+ });
+ })
+
it('fails to connect because the cert is not correct', function (done) {
if (skip) this.skip();
var faulty_cert = utils.clone(tls_options);
From 1a4c410b4179d68aee922b80aff583a336251163 Mon Sep 17 00:00:00 2001
From: calebboyd
Date: Tue, 9 Jan 2018 10:54:16 -0600
Subject: [PATCH 05/96] docs: add note about rediss usage
---
README.md | 4 +++-
lib/createClient.js | 4 ++--
test/tls.spec.js | 16 ++++++++--------
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index 1ec63dacdd..c3aabeb685 100644
--- a/README.md
+++ b/README.md
@@ -234,13 +234,15 @@ arguments. `createClient()` returns a `RedisClient` object. Otherwise,
__Tip:__ If the Redis server runs on the same machine as the client consider
using unix sockets if possible to increase throughput.
+__Note:__ Using `'rediss://...` for the protocol in a `redis_url` will enable a TLS socket connection. However, additional TLS options will need to be passed in `options`, if required.
+
#### `options` object properties
| Property | Default | Description |
|-----------|-----------|-------------|
| host | 127.0.0.1 | IP address of the Redis server |
| port | 6379 | Port of the Redis server |
| path | null | The UNIX socket string of the Redis server |
-| url | null | The URL of the Redis server. Format: `[redis:][rediss:]//[[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)). |
+| url | null | The URL of the Redis server. Format: `[redis[s]:]//[[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)). |
| 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. |
| 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. |
| return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. |
diff --git a/lib/createClient.js b/lib/createClient.js
index 8c3a8508a2..133f0b758e 100644
--- a/lib/createClient.js
+++ b/lib/createClient.js
@@ -31,10 +31,10 @@ module.exports = function createClient (port_arg, host_arg, options) {
if (parsed.auth) {
options.password = parsed.auth.split(':')[1];
}
- if (parsed.protocol && parsed.protocol !== 'redis:') {
+ if (parsed.protocol) {
if (parsed.protocol === 'rediss:') {
options.tls = options.tls || {};
- } else {
+ } else if (parsed.protocol !== 'redis:') {
console.warn('node_redis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!');
}
}
diff --git a/test/tls.spec.js b/test/tls.spec.js
index 6a7e021e33..3b0e18197a 100644
--- a/test/tls.spec.js
+++ b/test/tls.spec.js
@@ -7,6 +7,7 @@ var helper = require('./helper');
var path = require('path');
var redis = config.redis;
var utils = require('../lib/utils');
+var tls = require('tls');
var tls_options = {
servername: 'redis.js.org',
@@ -90,12 +91,12 @@ describe('TLS connection tests', function () {
it('connect with host and port provided in the tls object', function (done) {
if (skip) this.skip();
- var tls = utils.clone(tls_options);
- tls.port = tls_port;
- tls.host = 'localhost';
+ var tls_opts = utils.clone(tls_options);
+ tls_opts.port = tls_port;
+ tls_opts.host = 'localhost';
client = redis.createClient({
connect_timeout: 1000,
- tls: tls
+ tls: tls_opts
});
// verify connection is using TCP, not UNIX socket
@@ -109,17 +110,16 @@ describe('TLS connection tests', function () {
});
describe('using rediss as url protocol', function (done) {
- var tls = require('tls')
- var tlsConnect = tls.connect
+ var tls_connect = tls.connect
beforeEach(function () {
tls.connect = function (options) {
options = utils.clone(options)
options.ca = tls_options.ca;
- return tlsConnect.call(tls, options);
+ return tls_connect.call(tls, options);
}
})
afterEach(function () {
- tls.connect = tlsConnect;
+ tls.connect = tls_connect;
})
it('connect with tls when rediss is used as the protocol', function (done) {
if (skip) this.skip();
From 648e65a2bc74215d9d8755a7a6d3d146bca29b94 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 11 Feb 2018 14:18:34 +0000
Subject: [PATCH 06/96] swap out queue library
---
index.js | 2 +-
lib/multi.js | 2 +-
package.json | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/index.js b/index.js
index 58fcf84c6c..271d53db43 100644
--- a/index.js
+++ b/index.js
@@ -5,7 +5,7 @@ var tls = require('tls');
var util = require('util');
var utils = require('./lib/utils');
var Command = require('./lib/command');
-var Queue = require('double-ended-queue');
+var Queue = require('denque');
var errorClasses = require('./lib/customErrors');
var EventEmitter = require('events');
var Parser = require('redis-parser');
diff --git a/lib/multi.js b/lib/multi.js
index 63f5d21085..d89cffbbd4 100644
--- a/lib/multi.js
+++ b/lib/multi.js
@@ -1,6 +1,6 @@
'use strict';
-var Queue = require('double-ended-queue');
+var Queue = require('denque');
var utils = require('./utils');
var Command = require('./command');
diff --git a/package.json b/package.json
index 4b6d6e9456..c4e722ac01 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
"compare": "node benchmarks/diff_multi_bench_output.js beforeBench.txt afterBench.txt"
},
"dependencies": {
- "double-ended-queue": "^2.1.0-0",
+ "denque": "^1.2.3",
"redis-commands": "^1.2.0",
"redis-parser": "^2.6.0"
},
From cf0a323fbc71e26c03c137d849ff1d3d7bf49618 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 11 Feb 2018 14:34:50 +0000
Subject: [PATCH 07/96] utils spec change - forgot to push
---
test/utils.spec.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/utils.spec.js b/test/utils.spec.js
index e036d84167..0d9ae96c63 100644
--- a/test/utils.spec.js
+++ b/test/utils.spec.js
@@ -1,7 +1,7 @@
'use strict';
var assert = require('assert');
-var Queue = require('double-ended-queue');
+var Queue = require('denque');
var utils = require('../lib/utils');
var intercept = require('intercept-stdout');
From cc48de824869ba3a76026df4f92cca9562008e7b Mon Sep 17 00:00:00 2001
From: Tim Marshall
Date: Mon, 19 Feb 2018 11:09:40 -0800
Subject: [PATCH 08/96] consistent ;s
---
README.md | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index c3aabeb685..1b3de89d98 100644
--- a/README.md
+++ b/README.md
@@ -437,19 +437,19 @@ protocol. Any commands where client state is saved on the Redis server, e.g.
`*SUBSCRIBE` or the blocking `BL*` commands will *NOT* work with `.unref()`.
```js
-var redis = require("redis")
-var client = redis.createClient()
+var redis = require("redis");
+var client = redis.createClient();
/*
Calling unref() will allow this program to exit immediately after the get
command finishes. Otherwise the client would hang as long as the
client-server connection is alive.
*/
-client.unref()
-client.get("foo", function (err, value){
- if (err) throw(err)
- console.log(value)
-})
+client.unref();
+client.get("foo", function (err, value) {
+ if (err) throw(err);
+ console.log(value);
+});
```
## Friendlier hash commands
From e3a8706c6ef3b1f356e784968169795b8e0dafd5 Mon Sep 17 00:00:00 2001
From: Tim Marshall
Date: Mon, 19 Feb 2018 11:11:01 -0800
Subject: [PATCH 09/96] js highlighting
---
README.md | 44 ++++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/README.md b/README.md
index 1b3de89d98..a2375279f0 100644
--- a/README.md
+++ b/README.md
@@ -773,9 +773,11 @@ Note that this program will not exit cleanly because the client is still connect
To execute redis multi-word commands like `SCRIPT LOAD` or `CLIENT LIST` pass
the second word as first parameter:
- client.script('load', 'return 1');
- client.multi().script('load', 'return 1').exec(...);
- client.multi([['script', 'load', 'return 1']]).exec(...);
+```js
+client.script('load', 'return 1');
+client.multi().script('load', 'return 1').exec(...);
+client.multi([['script', 'load', 'return 1']]).exec(...);
+```
## client.duplicate([options][, callback])
@@ -790,24 +792,26 @@ blocking redis commands BRPOP, BLPOP, and BRPOPLPUSH. If these commands
are used on the same redisClient instance as non-blocking commands, the
non-blocking ones may be queued up until after the blocking ones finish.
- var Redis=require('redis');
- var client = Redis.createClient();
- var clientBlocking = client.duplicate();
+```js
+var Redis=require('redis');
+var client = Redis.createClient();
+var clientBlocking = client.duplicate();
- var get = function() {
- console.log("get called");
- client.get("any_key",function() { console.log("get returned"); });
- setTimeout( get, 1000 );
- };
- var brpop = function() {
- console.log("brpop called");
- clientBlocking.brpop("nonexistent", 5, function() {
- console.log("brpop return");
- setTimeout( brpop, 1000 );
- });
- };
- get();
- brpop();
+var get = function() {
+ console.log("get called");
+ client.get("any_key",function() { console.log("get returned"); });
+ setTimeout( get, 1000 );
+};
+var brpop = function() {
+ console.log("brpop called");
+ clientBlocking.brpop("nonexistent", 5, function() {
+ console.log("brpop return");
+ setTimeout( brpop, 1000 );
+ });
+};
+get();
+brpop();
+```
Another reason to use duplicate() is when multiple DBs on the same server are
accessed via the redis SELECT command. Each DB could use its own connection.
From 2a15fc8825d8fc34a5f629354a70b164f4231004 Mon Sep 17 00:00:00 2001
From: Tim Marshall
Date: Mon, 19 Feb 2018 11:12:28 -0800
Subject: [PATCH 10/96] fix indent
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index a2375279f0..414f75e9a4 100644
--- a/README.md
+++ b/README.md
@@ -961,7 +961,7 @@ ReplyError: ERR wrong number of arguments for 'set' command
## How to Contribute
- Open a pull request or an issue about what you want to implement / change. We're glad for any help!
- - Please be aware that we'll only accept fully tested code.
+- Please be aware that we'll only accept fully tested code.
## Contributors
From 19c80c617c864c2bdbf37623e9075cdcbacd098c Mon Sep 17 00:00:00 2001
From: Mark McNelis
Date: Fri, 23 Feb 2018 16:59:02 +0000
Subject: [PATCH 11/96] fix: client duplicate function now allows db param to
be passed
---
lib/extendedApi.js | 2 +-
test/node_redis.spec.js | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/extendedApi.js b/lib/extendedApi.js
index bac3691413..27ed4215d6 100644
--- a/lib/extendedApi.js
+++ b/lib/extendedApi.js
@@ -95,7 +95,7 @@ RedisClient.prototype.duplicate = function (options, callback) {
existing_options[elem] = options[elem];
}
var client = new RedisClient(existing_options);
- client.selected_db = this.selected_db;
+ client.selected_db = options.db || this.selected_db;
if (typeof callback === 'function') {
var ready_listener = function () {
callback(null, client);
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index 1557730312..3375b759d9 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -120,11 +120,14 @@ describe('The node_redis client', function () {
});
it('check if all new options replaced the old ones', function (done) {
+ client.selected_db = 1;
var client2 = client.duplicate({
+ db: 2,
no_ready_check: true
});
assert(client.connected);
assert(!client2.connected);
+ assert.notEqual(client.selected_db, client2.selected_db);
assert.strictEqual(client.options.no_ready_check, undefined);
assert.strictEqual(client2.options.no_ready_check, true);
assert.notDeepEqual(client.options, client2.options);
From 7ba8163a7fc178c3ddebcc484e7f96fe0e97d95e Mon Sep 17 00:00:00 2001
From: Chris
Date: Tue, 27 Mar 2018 22:28:50 -0700
Subject: [PATCH 12/96] update readme to reflect usage of .add_command
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 414f75e9a4..534138a48f 100644
--- a/README.md
+++ b/README.md
@@ -826,7 +826,7 @@ Redis.
All commands are sent as multi-bulk commands. `args` can either be an Array of
arguments, or omitted / set to undefined.
-## client.add_command(command_name)
+## redis.add_command(command_name)
Calling add_command will add a new command to the prototype. The exact command
name will be used when calling using this new command. Using arbitrary arguments
From c57d62c857f30ab0eeb257041bcc6fa1a41a4605 Mon Sep 17 00:00:00 2001
From: Ingo Fischer
Date: Tue, 3 Apr 2018 14:31:24 +0200
Subject: [PATCH 13/96] te,porary solution to enable IPv6 on travis-ci in
trusty images
---
.travis.yml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 51745c8819..f2422e979b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,5 @@
language: node_js
-sudo: false
+sudo: required
env:
- CXX=g++-4.8 TRAVIS=true
addons:
@@ -15,3 +15,9 @@ node_js:
- "6"
- "8"
after_success: npm run coveralls
+before_script:
+ # Add an IPv6 config - see the corresponding Travis issue
+ # https://github.com/travis-ci/travis-ci/issues/8361
+ - if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
+ sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6';
+ fi
From 6b294db7a22bc709b53b601e913d0f583e2c6936 Mon Sep 17 00:00:00 2001
From: Ingo Fischer
Date: Tue, 3 Apr 2018 14:32:14 +0200
Subject: [PATCH 14/96] fix test because error message seems changed
---
test/commands/select.spec.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/commands/select.spec.js b/test/commands/select.spec.js
index 4297dca7f3..fc054a7e4a 100644
--- a/test/commands/select.spec.js
+++ b/test/commands/select.spec.js
@@ -72,7 +72,7 @@ describe("The 'select' method", function () {
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined');
client.select(9999, function (err) {
assert.equal(err.code, 'ERR');
- assert.equal(err.message, 'ERR invalid DB index');
+ assert.equal(err.message, 'ERR DB index is out of range');
done();
});
});
@@ -97,7 +97,7 @@ describe("The 'select' method", function () {
client.on('error', function (err) {
assert.strictEqual(err.command, 'SELECT');
- assert.equal(err.message, 'ERR invalid DB index');
+ assert.equal(err.message, 'ERR DB index is out of range');
done();
});
From 673b1770756bca1ffa912e911f799657ca4e259d Mon Sep 17 00:00:00 2001
From: Ingo Fischer
Date: Tue, 3 Apr 2018 21:27:45 +0200
Subject: [PATCH 15/96] accept both error messages (win!=Linux)
---
test/commands/select.spec.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/commands/select.spec.js b/test/commands/select.spec.js
index fc054a7e4a..1dff2025d9 100644
--- a/test/commands/select.spec.js
+++ b/test/commands/select.spec.js
@@ -72,7 +72,7 @@ describe("The 'select' method", function () {
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined');
client.select(9999, function (err) {
assert.equal(err.code, 'ERR');
- assert.equal(err.message, 'ERR DB index is out of range');
+ assert((err.message == 'ERR DB index is out of range' || err.message == 'ERR invalid DB index'));
done();
});
});
@@ -97,7 +97,7 @@ describe("The 'select' method", function () {
client.on('error', function (err) {
assert.strictEqual(err.command, 'SELECT');
- assert.equal(err.message, 'ERR DB index is out of range');
+ assert((err.message == 'ERR DB index is out of range' || err.message == 'ERR invalid DB index'));
done();
});
From 59db10d2be4c6b761263fa4c16c596784a49f050 Mon Sep 17 00:00:00 2001
From: Gonen Dukas
Date: Wed, 25 Apr 2018 13:18:10 +0300
Subject: [PATCH 16/96] Simpler promisifyAll example
---
README.md | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 534138a48f..60b408c9fb 100644
--- a/README.md
+++ b/README.md
@@ -86,8 +86,7 @@ You can also use node_redis with promises by promisifying node_redis with
```js
const redis = require('redis');
-bluebird.promisifyAll(redis.RedisClient.prototype);
-bluebird.promisifyAll(redis.Multi.prototype);
+bluebird.promisifyAll(redis);
```
It'll add a *Async* to all node_redis functions (e.g. return client.getAsync().then())
From 35facdb1fb5945a358d00b48a6282c91a7e3165c Mon Sep 17 00:00:00 2001
From: chestermax01
Date: Mon, 21 May 2018 15:46:30 +0800
Subject: [PATCH 17/96] Adapt Alibaba Cloud kvstore
---
lib/createClient.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/createClient.js b/lib/createClient.js
index 133f0b758e..13c213470a 100644
--- a/lib/createClient.js
+++ b/lib/createClient.js
@@ -29,7 +29,7 @@ module.exports = function createClient (port_arg, host_arg, options) {
// [redis:]//[[user][:password]@][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]
if (parsed.slashes) { // We require slashes
if (parsed.auth) {
- options.password = parsed.auth.split(':')[1];
+ options.password = parsed.auth.slice(parsed.auth.indexOf(':') + 1);
}
if (parsed.protocol) {
if (parsed.protocol === 'rediss:') {
From c159815e62af9032aca8bd52602541ddd2e25894 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Tue, 22 May 2018 22:04:47 +0100
Subject: [PATCH 18/96] update utils.spec queue tests to support denque push()
differences
---
test/utils.spec.js | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/test/utils.spec.js b/test/utils.spec.js
index 0d9ae96c63..592600fb6d 100644
--- a/test/utils.spec.js
+++ b/test/utils.spec.js
@@ -131,17 +131,22 @@ describe('utils.js', function () {
});
it('elements in the offline queue. Reply after the offline queue is empty and respect the command_obj callback', function (done) {
- clientMock.offline_queue.push(create_command_obj(), create_command_obj());
+ clientMock.offline_queue.push(create_command_obj());
+ clientMock.offline_queue.push(create_command_obj());
utils.reply_in_order(clientMock, function () {
assert.strictEqual(clientMock.offline_queue.length, 0);
assert.strictEqual(res_count, 2);
done();
}, null, null);
- while (clientMock.offline_queue.length) clientMock.offline_queue.shift().callback(null, 'foo');
+ while (clientMock.offline_queue.length) {
+ clientMock.offline_queue.shift().callback(null, 'foo');
+ }
});
it('elements in the offline queue. Reply after the offline queue is empty and respect the command_obj error emit', function (done) {
- clientMock.command_queue.push({}, create_command_obj(), {});
+ clientMock.command_queue.push({});
+ clientMock.command_queue.push(create_command_obj());
+ clientMock.command_queue.push({});
utils.reply_in_order(clientMock, function () {
assert.strictEqual(clientMock.command_queue.length, 0);
assert(emitted);
@@ -158,8 +163,10 @@ describe('utils.js', function () {
});
it('elements in the offline queue and the command_queue. Reply all other commands got handled respect the command_obj', function (done) {
- clientMock.command_queue.push(create_command_obj(), create_command_obj());
- clientMock.offline_queue.push(create_command_obj(), {});
+ clientMock.command_queue.push(create_command_obj());
+ clientMock.command_queue.push(create_command_obj());
+ clientMock.command_queue.push(create_command_obj());
+ clientMock.offline_queue.push({});
utils.reply_in_order(clientMock, function (err, res) {
assert.strictEqual(clientMock.command_queue.length, 0);
assert.strictEqual(clientMock.offline_queue.length, 0);
From 0dc626262cf7f18c9b61d5edb9b39efc071d21f2 Mon Sep 17 00:00:00 2001
From: Pedro Miguel Pereira Serrano Martins
Date: Sun, 10 Jun 2018 10:44:51 +0200
Subject: [PATCH 19/96] Added documentation for REDIS optimistic lock system.
---
README.md | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
diff --git a/README.md b/README.md
index 60b408c9fb..d2e9b90583 100644
--- a/README.md
+++ b/README.md
@@ -704,6 +704,99 @@ significantly compared to firing the same commands in a loop without waiting for
the result! See the benchmarks for further comparison. Please remember that all
commands are kept in memory until they are fired.
+## Optimistic Locks
+
+Using `multi` you can make sure your modifications run as a transaction, but you
+can't be sure you got there first. What if another client modified a key while
+you were working with it's data?
+
+To solve this, Redis supports the [WATCH](https://redis.io/topics/transactions)
+command, which is meant to be used with MULTI:
+
+```js
+var redis = require("redis"),
+ client = redis.createClient();
+
+client.watch("foo", function( err ){
+ if(err) throw err;
+
+ client.get("foo", function(err, result) {
+ if(err) throw err;
+
+ // Process result
+ // Heavy and time consuming operation here
+
+ client.multi()
+ .set("foo", "some heavy computation")
+ .exec(function(err, results) {
+
+ /**
+ * If err is null, it means Redis successfully attempted
+ * the operation.
+ */
+ if(err) throw err;
+
+ /**
+ * If results === null, it means that a concurrent client
+ * changed the key while we were processing it and thus
+ * the execution of the MULTI command was not performed.
+ *
+ * NOTICE: Failing an execution of MULTI is not considered
+ * an error. So you will have err === null and results === null
+ */
+
+ });
+ });
+});
+```
+
+The above snippet shows the correct usage of `watch` with `multi`. Every time a
+watched key is changed before the execution of a `multi` command, the execution
+will return `null`. On a normal situation, the execution will return an array of
+values with the results of the operations.
+
+As stated in the snippet, failing the execution of a `multi` command being watched
+is not considered an error. The execution may return an error if, for example, the
+client cannot connect to Redis.
+
+An example where we can see the execution of a `multi` command fail is as follows:
+
+```js
+let clients = {};
+clients.watcher = redis.createClient({ ... } );
+clients.alterer = clients.watcher.duplicate();
+
+clients.watcher.watch('foo',function(err) {
+ if (err) { throw err; }
+ //if you comment out the next line, the transaction will work
+ clients.alterer.set('foo',Math.random(), (err) => {if (err) { throw err; }})
+
+ //using a setTimeout here to ensure that the MULTI/EXEC will come after the SET.
+ //Normally, you would use a callback to ensure order, but I want the above SET command
+ //to be easily comment-out-able.
+ setTimeout(function() {
+ clients.watcher
+ .multi()
+ .set('foo','abc')
+ .set('bar','1234')
+ .exec((err,results) => {
+ if (err) { throw err; }
+ if (results === null) {
+ console.log('transaction aborted because results were null');
+ } else {
+ console.log('transaction worked and returned',results)
+ }
+ clients.watcher.quit();
+ clients.alterer.quit();
+ });
+ },1000);
+});
+```
+
+**NOTE**: Redis WATCH does not work on fields of hashes and other objects. You can watch a hash
+to see if anything inside it was modified, but you cannot watch a specific hash field for a
+modification.
+
## Monitor mode
Redis supports the `MONITOR` command, which lets you see all commands received
From 7b575780f6ed6790b1f28aa14555bae2150ad017 Mon Sep 17 00:00:00 2001
From: Pedro Miguel Pereira Serrano Martins
Date: Sun, 10 Jun 2018 19:02:25 +0200
Subject: [PATCH 20/96] Improved QA of code snippets, improved documentatino on
WATCH limitations.
---
README.md | 37 +++++++++++++++++++++++++++++++++----
1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index d2e9b90583..ff15de9355 100644
--- a/README.md
+++ b/README.md
@@ -715,7 +715,7 @@ command, which is meant to be used with MULTI:
```js
var redis = require("redis"),
- client = redis.createClient();
+ client = redis.createClient({ ... });
client.watch("foo", function( err ){
if(err) throw err;
@@ -793,9 +793,38 @@ clients.watcher.watch('foo',function(err) {
});
```
-**NOTE**: Redis WATCH does not work on fields of hashes and other objects. You can watch a hash
-to see if anything inside it was modified, but you cannot watch a specific hash field for a
-modification.
+### WATCH limitations
+
+Redis WATCH works only on *whole* key values. For example, with WATCH you can
+watch a hash for modifications, but you cannot watch a specific field of a hash.
+
+The following example would watch the keys `foo` and `hello`, not the field `hello`
+of hash `foo`:
+
+```js
+var redis = require("redis"),
+ client = redis.createClient({ ... });
+
+client.hget( "foo", "hello", function(err, result){
+
+ //Do some processing with the value from this field and watch it after
+
+ client.watch("foo", "hello", function( err ){
+ if(err) throw err;
+
+ /**
+ * WRONG: This is now watching the keys 'foo' and 'hello'. It is not
+ * watching the field 'hello' of hash 'foo'. Because the key 'foo'
+ * refers to a hash, this command is now watching the entire hash
+ * for modifications.
+ */
+ });
+} )
+
+```
+
+This limitation also applies to sets ( cannot watch individual set members )
+and any other collections.
## Monitor mode
From 7ab0804a27a7b9dc86bd58eb3a5d18f04d7c3eff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Akseli=20Pal=C3=A9n?=
Date: Thu, 21 Jun 2018 14:18:29 +0300
Subject: [PATCH 21/96] Clarify reconnecting delay
Without clarification `delay` can mean two things: time to the next attempt (wrong) or time passed from the previous attempt (correct). The wrong interpretation is tempting because it makes easy to print "Trying to reconnect in {delay} ms."
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index ff15de9355..04c653e44c 100644
--- a/README.md
+++ b/README.md
@@ -180,7 +180,7 @@ emitted.
`client` will emit `reconnecting` when trying to reconnect to the Redis server
after losing the connection. Listeners are passed an object containing `delay`
-(in ms) and `attempt` (the attempt #) attributes.
+(in ms from the previous try) and `attempt` (the attempt #) attributes.
### "error"
From 62f30c08cbc9f83a0443f281f2bbd964003c22e9 Mon Sep 17 00:00:00 2001
From: Mario Daskalov
Date: Fri, 10 Aug 2018 17:14:44 +0300
Subject: [PATCH 22/96] Update client.quit definition in README.md to include
callback
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 04c653e44c..eb05cc864f 100644
--- a/README.md
+++ b/README.md
@@ -329,7 +329,7 @@ implement backpressure by checking the buffer state before sending a command and
listening to the stream
[drain](https://nodejs.org/api/stream.html#stream_event_drain) event.
-## client.quit()
+## client.quit(callback)
This sends the quit command to the redis server and ends cleanly right after all
running commands were properly handled. If this is called while reconnecting
From 6bb90bff5a423fea7684324dc48f76940cdb258b Mon Sep 17 00:00:00 2001
From: Vasyl Boroviak
Date: Wed, 22 Aug 2018 12:01:50 +1000
Subject: [PATCH 23/96] Avoid distributing unnecessary development files
---
.npmignore | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.npmignore b/.npmignore
index b0238e058c..569f3efb2b 100644
--- a/.npmignore
+++ b/.npmignore
@@ -3,6 +3,9 @@ benchmarks/
test/
.nyc_output/
coverage/
+.github/
+.eslintignore
+.eslintrc
.tern-port
*.log
*.rdb
From 96fdc7794bbdf86bec13421a18c786fec18b0159 Mon Sep 17 00:00:00 2001
From: Guy Korland
Date: Mon, 12 Nov 2018 17:36:41 +0200
Subject: [PATCH 24/96] add a simple streams example
---
examples/streams.js | 47 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 examples/streams.js
diff --git a/examples/streams.js b/examples/streams.js
new file mode 100644
index 0000000000..1aeeca0a08
--- /dev/null
+++ b/examples/streams.js
@@ -0,0 +1,47 @@
+'use strict';
+
+var redis = require('redis');
+var client1 = redis.createClient();
+var client2 = redis.createClient();
+var client3 = redis.createClient();
+
+client1.xadd('mystream', '*', 'field1', 'm1', function (err) {
+ if(err){
+ return console.error(err);
+ }
+ client1.xgroup('CREATE', 'mystream', 'mygroup', '$', function (err) {
+ if(err){
+ return console.error(err);
+ }
+ });
+
+ client2.xreadgroup('GROUP', 'mygroup', 'consumer', 'Block', 1000,
+ 'STREAMS', 'mystream', '>', function (err, stream) {
+ if(err){
+ return console.error(err);
+ }
+ console.log('client2 ' + stream);
+ });
+
+ client3.xreadgroup('GROUP', 'mygroup', 'consumer', 'Block', 1000,
+ 'STREAMS', 'mystream', '>', function (err, stream) {
+ if(err){
+ return console.error(err);
+ }
+ console.log('client3 ' + stream);
+ });
+
+
+ client1.xadd('mystream', '*', 'field1', 'm2', function (err) {
+ if(err){
+ return console.error(err);
+ }
+ });
+
+ client1.xadd('mystream', '*', 'field1', 'm3', function (err) {
+ if(err){
+ return console.error(err);
+ }
+ });
+
+});
From 383f09702981fe55fed914af8d725084fb2ce0fe Mon Sep 17 00:00:00 2001
From: Guy Korland
Date: Wed, 14 Nov 2018 04:51:56 +0200
Subject: [PATCH 25/96] Added 'NOACK' to xreadgroup call
Added 'NOACK' to xreadgroup call, to make sure entries are auto ACK
---
examples/streams.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/examples/streams.js b/examples/streams.js
index 1aeeca0a08..2fda1293ce 100644
--- a/examples/streams.js
+++ b/examples/streams.js
@@ -15,7 +15,7 @@ client1.xadd('mystream', '*', 'field1', 'm1', function (err) {
}
});
- client2.xreadgroup('GROUP', 'mygroup', 'consumer', 'Block', 1000,
+ client2.xreadgroup('GROUP', 'mygroup', 'consumer', 'Block', 1000, 'NOACK',
'STREAMS', 'mystream', '>', function (err, stream) {
if(err){
return console.error(err);
@@ -23,7 +23,7 @@ client1.xadd('mystream', '*', 'field1', 'm1', function (err) {
console.log('client2 ' + stream);
});
- client3.xreadgroup('GROUP', 'mygroup', 'consumer', 'Block', 1000,
+ client3.xreadgroup('GROUP', 'mygroup', 'consumer', 'Block', 1000, 'NOACK',
'STREAMS', 'mystream', '>', function (err, stream) {
if(err){
return console.error(err);
From 8ee1b9822b1d42f57bb84dcc86d8727266bd5e4c Mon Sep 17 00:00:00 2001
From: Xin
Date: Thu, 29 Nov 2018 11:59:44 +1100
Subject: [PATCH 26/96] add option socket_initialdelay
---
index.js | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/index.js b/index.js
index 271d53db43..ce667a9dd4 100644
--- a/index.js
+++ b/index.js
@@ -101,6 +101,10 @@ function RedisClient (options, stream) {
if (options.socket_keepalive === undefined) {
options.socket_keepalive = true;
}
+ if (options.socket_initialdelay === undefined) {
+ options.socket_initialdelay = 0;
+ // set default to 0, which is aligned to https://nodejs.org/api/net.html#net_socket_setkeepalive_enable_initialdelay
+ }
for (var command in options.rename_commands) {
options.rename_commands[command.toLowerCase()] = options.rename_commands[command];
}
@@ -416,7 +420,7 @@ RedisClient.prototype.on_connect = function () {
this.connected = true;
this.ready = false;
this.emitted_end = false;
- this.stream.setKeepAlive(this.options.socket_keepalive);
+ this.stream.setKeepAlive(this.options.socket_keepalive, this.options.socket_initialdelay);
this.stream.setTimeout(0);
this.emit('connect');
From 3a615e825208d99630d9f64a4dd38276a803fb23 Mon Sep 17 00:00:00 2001
From: Xin
Date: Thu, 29 Nov 2018 12:02:31 +1100
Subject: [PATCH 27/96] add comment for socket_initialdelay
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index eb05cc864f..b208915991 100644
--- a/README.md
+++ b/README.md
@@ -247,6 +247,7 @@ __Note:__ Using `'rediss://...` for the protocol in a `redis_url` will enable a
| return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. |
| 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. |
| socket_keepalive | true | If set to `true`, the keep-alive functionality is enabled on the underlying socket. |
+| socket_initialdelay | 0 | Initial Delay in milliseconds, and this will also behave the interval keep alive message sending to Redis. |
| no_ready_check | false | When a connection is established to the Redis server, the server might still be loading the database from disk. While loading, the server will not respond to any commands. To work around this, `node_redis` has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command indicates whether the server is ready for more commands. When ready, `node_redis` emits a `ready` event. Setting `no_ready_check` to `true` will inhibit this check. |
| enable_offline_queue | true | By default, if there is no active connection to the Redis server, commands are added to a queue and are executed once the connection has been established. Setting `enable_offline_queue` to `false` will disable this feature and the callback will be executed immediately with an error, or an error will be emitted if no callback is specified. |
| retry_max_delay | null | __Deprecated__ _Please use `retry_strategy` instead._ By default, every time the client tries to connect and fails, the reconnection delay almost doubles. This delay normally grows infinitely, but setting `retry_max_delay` limits it to the maximum value provided in milliseconds. |
From 34eac0db40967b231907a5835453da75de93a91f Mon Sep 17 00:00:00 2001
From: Thomas Hunter II
Date: Thu, 27 Dec 2018 14:53:01 -0800
Subject: [PATCH 28/96] Fix typo in createClient.js
---
lib/createClient.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/createClient.js b/lib/createClient.js
index 13c213470a..1533d73d1b 100644
--- a/lib/createClient.js
+++ b/lib/createClient.js
@@ -72,7 +72,7 @@ module.exports = function createClient (port_arg, host_arg, options) {
options.host = options.host || host_arg;
if (port_arg && arguments.length !== 1) {
- throw new TypeError('To many arguments passed to createClient. Please only pass the options object');
+ throw new TypeError('Too many arguments passed to createClient. Please only pass the options object');
}
}
From 06635b77cc07ac34ebde633264f668f837ae9f97 Mon Sep 17 00:00:00 2001
From: andy addington
Date: Thu, 17 Jan 2019 06:56:41 -0800
Subject: [PATCH 29/96] test: Fix typo in assertEquals message
---
test/unify_options.spec.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/unify_options.spec.js b/test/unify_options.spec.js
index eb441d81a6..40bdf22a8b 100644
--- a/test/unify_options.spec.js
+++ b/test/unify_options.spec.js
@@ -209,7 +209,7 @@ describe('createClient options', function () {
}, undefined);
throw new Error('failed');
} catch (err) {
- assert.strictEqual(err.message, 'To many arguments passed to createClient. Please only pass the options object');
+ assert.strictEqual(err.message, 'Too many arguments passed to createClient. Please only pass the options object');
}
});
From 171cbc5a096745a3247fafc1785f93e1a709aaf1 Mon Sep 17 00:00:00 2001
From: Andy Ganchrow
Date: Tue, 5 Feb 2019 09:02:04 -0800
Subject: [PATCH 30/96] Fix typo in index.js
---
index.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/index.js b/index.js
index ce667a9dd4..ae0848cd62 100644
--- a/index.js
+++ b/index.js
@@ -205,7 +205,7 @@ function create_parser (self) {
err.message += '. Please report this.';
self.ready = false;
self.flush_and_error({
- message: 'Fatal error encountert. Command aborted.',
+ message: 'Fatal error encountered. Command aborted.',
code: 'NR_FATAL'
}, {
error: err,
@@ -1106,4 +1106,4 @@ require('./lib/individualCommands');
require('./lib/extendedApi');
//enables adding new commands (for modules and new commands)
-exports.addCommand = exports.add_command = require('./lib/commands');
\ No newline at end of file
+exports.addCommand = exports.add_command = require('./lib/commands');
From 128ca62346bf15c3813d9e45fe194ec1e4ca8f3c Mon Sep 17 00:00:00 2001
From: Andy Ganchrow
Date: Tue, 5 Feb 2019 11:06:16 -0800
Subject: [PATCH 31/96] test: Fix typo encountert in test
---
test/node_redis.spec.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index 3375b759d9..fe9a35c279 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -904,7 +904,7 @@ describe('The node_redis client', function () {
});
client.once('ready', function () {
client.set('foo', 'bar', function (err, res) {
- assert.strictEqual(err.message, 'Fatal error encountert. Command aborted. It might have been processed.');
+ assert.strictEqual(err.message, 'Fatal error encountered. Command aborted. It might have been processed.');
assert.strictEqual(err.code, 'NR_FATAL');
assert(err instanceof redis.AbortError);
error = err.origin;
From 50b4009005a7adf1d3fa2af2739dac402ca7f9fc Mon Sep 17 00:00:00 2001
From: JinHyuk Kim
Date: Wed, 6 Feb 2019 23:19:03 +0900
Subject: [PATCH 32/96] fix incorrect code for eslint rules (#1367)
* fix code for eslint rules
---
test/batch.spec.js | 68 +++++++++++++++++------------------
test/commands/select.spec.js | 4 +--
test/connection.spec.js | 2 +-
test/lib/redis-process.js | 25 ++++++-------
test/multi.spec.js | 70 ++++++++++++++++++------------------
test/node_redis.spec.js | 2 +-
test/tls.spec.js | 12 +++----
7 files changed, 92 insertions(+), 91 deletions(-)
diff --git a/test/batch.spec.js b/test/batch.spec.js
index 762b2f7049..df038e77e6 100644
--- a/test/batch.spec.js
+++ b/test/batch.spec.js
@@ -187,12 +187,12 @@ describe("The 'batch' method", function () {
['del', 'some set'],
['smembers', 'some set', undefined] // The explicit undefined is handled as a callback that is undefined
])
- .scard('some set')
- .exec(function (err, replies) {
- assert.strictEqual(4, replies[0].length);
- assert.strictEqual(0, replies[2].length);
- return done();
- });
+ .scard('some set')
+ .exec(function (err, replies) {
+ assert.strictEqual(4, replies[0].length);
+ assert.strictEqual(0, replies[2].length);
+ return done();
+ });
});
it('allows multiple operations to be performed using constructor with all kinds of syntax', function (done) {
@@ -213,29 +213,29 @@ describe("The 'batch' method", function () {
['HMSET', 'batchhmset', ['batchbar', 'batchbaz']],
['hmset', 'batchhmset', ['batchbar', 'batchbaz'], helper.isString('OK')],
])
- .hmget(now, 123456789, 'otherTypes')
- .hmget('key2', arr2, function noop () {})
- .hmget(['batchhmset2', 'some manner of key', 'batchbar3'])
- .mget('batchfoo2', ['batchfoo3', 'batchfoo'], function (err, res) {
- assert.strictEqual(res[0], 'batchbar2');
- assert.strictEqual(res[1], 'batchbar3');
- assert.strictEqual(res[2], null);
- })
- .exec(function (err, replies) {
- assert.equal(arr.length, 3);
- assert.equal(arr2.length, 2);
- assert.equal(arr3.length, 3);
- assert.equal(arr4.length, 3);
- assert.strictEqual(null, err);
- assert.equal(replies[10][1], '555');
- assert.equal(replies[11][0], 'a type of value');
- assert.strictEqual(replies[12][0], null);
- assert.equal(replies[12][1], 'test');
- assert.equal(replies[13][0], 'batchbar2');
- assert.equal(replies[13].length, 3);
- assert.equal(replies.length, 14);
- return done();
- });
+ .hmget(now, 123456789, 'otherTypes')
+ .hmget('key2', arr2, function noop () {})
+ .hmget(['batchhmset2', 'some manner of key', 'batchbar3'])
+ .mget('batchfoo2', ['batchfoo3', 'batchfoo'], function (err, res) {
+ assert.strictEqual(res[0], 'batchbar2');
+ assert.strictEqual(res[1], 'batchbar3');
+ assert.strictEqual(res[2], null);
+ })
+ .exec(function (err, replies) {
+ assert.equal(arr.length, 3);
+ assert.equal(arr2.length, 2);
+ assert.equal(arr3.length, 3);
+ assert.equal(arr4.length, 3);
+ assert.strictEqual(null, err);
+ assert.equal(replies[10][1], '555');
+ assert.equal(replies[11][0], 'a type of value');
+ assert.strictEqual(replies[12][0], null);
+ assert.equal(replies[12][1], 'test');
+ assert.equal(replies[13][0], 'batchbar2');
+ assert.equal(replies[13].length, 3);
+ assert.equal(replies.length, 14);
+ return done();
+ });
});
it('converts a non string key to a string', function (done) {
@@ -316,11 +316,11 @@ describe("The 'batch' method", function () {
['mget', ['batchfoo', 'some', 'random value', 'keys']],
['incr', 'batchfoo']
])
- .exec(function (err, replies) {
- assert.strictEqual(replies.length, 2);
- assert.strictEqual(replies[0].length, 4);
- return done();
- });
+ .exec(function (err, replies) {
+ assert.strictEqual(replies.length, 2);
+ assert.strictEqual(replies[0].length, 4);
+ return done();
+ });
});
it('allows multiple operations to be performed on a hash', function (done) {
diff --git a/test/commands/select.spec.js b/test/commands/select.spec.js
index 1dff2025d9..66a66f389b 100644
--- a/test/commands/select.spec.js
+++ b/test/commands/select.spec.js
@@ -72,7 +72,7 @@ describe("The 'select' method", function () {
assert.strictEqual(client.selected_db, undefined, 'default db should be undefined');
client.select(9999, function (err) {
assert.equal(err.code, 'ERR');
- assert((err.message == 'ERR DB index is out of range' || err.message == 'ERR invalid DB index'));
+ assert((err.message === 'ERR DB index is out of range' || err.message === 'ERR invalid DB index'));
done();
});
});
@@ -97,7 +97,7 @@ describe("The 'select' method", function () {
client.on('error', function (err) {
assert.strictEqual(err.command, 'SELECT');
- assert((err.message == 'ERR DB index is out of range' || err.message == 'ERR invalid DB index'));
+ assert((err.message === 'ERR DB index is out of range' || err.message === 'ERR invalid DB index'));
done();
});
diff --git a/test/connection.spec.js b/test/connection.spec.js
index f92dca1949..c33d1b8a83 100644
--- a/test/connection.spec.js
+++ b/test/connection.spec.js
@@ -376,7 +376,7 @@ describe('connection tests', function () {
var add = process.platform !== 'win32' ? 15 : 200;
var now = Date.now();
assert(now - time < connect_timeout + add, 'The real timeout time should be below ' + (connect_timeout + add) + 'ms but is: ' + (now - time));
- // Timers sometimes trigger early (e.g. 1ms to early)
+ // Timers sometimes trigger early (e.g. 1ms to early)
assert(now - time >= connect_timeout - 5, 'The real timeout time should be above ' + connect_timeout + 'ms, but it is: ' + (now - time));
done();
});
diff --git a/test/lib/redis-process.js b/test/lib/redis-process.js
index e98f7fbffc..c46fd8d70f 100644
--- a/test/lib/redis-process.js
+++ b/test/lib/redis-process.js
@@ -27,20 +27,21 @@ function waitForRedis (available, cb, port) {
bluebird.join(
tcpPortUsed.check(port, '127.0.0.1'),
tcpPortUsed.check(port, '::1'),
- function (ipV4, ipV6) {
- if (ipV6 === available && ipV4 === available) {
- if (fs.existsSync(socket) === available) {
- clearInterval(id);
- return cb();
+ function (ipV4, ipV6) {
+ if (ipV6 === available && ipV4 === available) {
+ if (fs.existsSync(socket) === available) {
+ clearInterval(id);
+ return cb();
+ }
+ // The same message applies for can't stop but we ignore that case
+ throw new Error('Port ' + port + ' is already in use. Tests can\'t start.\n');
}
- // The same message applies for can't stop but we ignore that case
- throw new Error('Port ' + port + ' is already in use. Tests can\'t start.\n');
+ if (Date.now() - time > 6000) {
+ throw new Error('Redis could not start on port ' + (port || config.PORT) + '\n');
+ }
+ running = false;
}
- if (Date.now() - time > 6000) {
- throw new Error('Redis could not start on port ' + (port || config.PORT) + '\n');
- }
- running = false;
- }).catch(function (err) {
+ ).catch(function (err) {
console.error('\x1b[31m' + err.stack + '\x1b[0m\n');
process.exit(1);
});
diff --git a/test/multi.spec.js b/test/multi.spec.js
index e654375dc8..33ffdbe16c 100644
--- a/test/multi.spec.js
+++ b/test/multi.spec.js
@@ -379,12 +379,12 @@ describe("The 'multi' method", function () {
['del', 'some set'],
['smembers', 'some set']
])
- .scard('some set')
- .exec(function (err, replies) {
- assert.strictEqual(4, replies[0].length);
- assert.strictEqual(0, replies[2].length);
- return done();
- });
+ .scard('some set')
+ .exec(function (err, replies) {
+ assert.strictEqual(4, replies[0].length);
+ assert.strictEqual(0, replies[2].length);
+ return done();
+ });
});
it('allows multiple operations to be performed using constructor with all kinds of syntax', function (done) {
@@ -406,30 +406,30 @@ describe("The 'multi' method", function () {
['HMSET', 'multihmset', ['multibar', 'multibaz'], undefined], // undefined is used as a explicit not set callback variable
['hmset', 'multihmset', ['multibar', 'multibaz'], helper.isString('OK')],
])
- .hmget(now, 123456789, 'otherTypes')
- .hmget('key2', arr2, function noop () {})
- .hmget(['multihmset2', 'some manner of key', 'multibar3'])
- .mget('multifoo2', ['multifoo3', 'multifoo'], function (err, res) {
- assert(res[0], 'multifoo3');
- assert(res[1], 'multifoo');
- called = true;
- })
- .exec(function (err, replies) {
- assert(called);
- assert.equal(arr.length, 3);
- assert.equal(arr2.length, 2);
- assert.equal(arr3.length, 3);
- assert.equal(arr4.length, 3);
- assert.strictEqual(null, err);
- assert.equal(replies[10][1], '555');
- assert.equal(replies[11][0], 'a type of value');
- assert.strictEqual(replies[12][0], null);
- assert.equal(replies[12][1], 'test');
- assert.equal(replies[13][0], 'multibar2');
- assert.equal(replies[13].length, 3);
- assert.equal(replies.length, 14);
- return done();
- });
+ .hmget(now, 123456789, 'otherTypes')
+ .hmget('key2', arr2, function noop () {})
+ .hmget(['multihmset2', 'some manner of key', 'multibar3'])
+ .mget('multifoo2', ['multifoo3', 'multifoo'], function (err, res) {
+ assert(res[0], 'multifoo3');
+ assert(res[1], 'multifoo');
+ called = true;
+ })
+ .exec(function (err, replies) {
+ assert(called);
+ assert.equal(arr.length, 3);
+ assert.equal(arr2.length, 2);
+ assert.equal(arr3.length, 3);
+ assert.equal(arr4.length, 3);
+ assert.strictEqual(null, err);
+ assert.equal(replies[10][1], '555');
+ assert.equal(replies[11][0], 'a type of value');
+ assert.strictEqual(replies[12][0], null);
+ assert.equal(replies[12][1], 'test');
+ assert.equal(replies[13][0], 'multibar2');
+ assert.equal(replies[13].length, 3);
+ assert.equal(replies.length, 14);
+ return done();
+ });
});
it('converts a non string key to a string', function (done) {
@@ -505,11 +505,11 @@ describe("The 'multi' method", function () {
['mget', ['multifoo', 'some', 'random value', 'keys']],
['incr', 'multifoo']
])
- .exec(function (err, replies) {
- assert.strictEqual(replies.length, 2);
- assert.strictEqual(replies[0].length, 4);
- return done();
- });
+ .exec(function (err, replies) {
+ assert.strictEqual(replies.length, 2);
+ assert.strictEqual(replies[0].length, 4);
+ return done();
+ });
});
it('allows multiple operations to be performed on a hash', function (done) {
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index fe9a35c279..e553f8521e 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -122,7 +122,7 @@ describe('The node_redis client', function () {
it('check if all new options replaced the old ones', function (done) {
client.selected_db = 1;
var client2 = client.duplicate({
- db: 2,
+ db: 2,
no_ready_check: true
});
assert(client.connected);
diff --git a/test/tls.spec.js b/test/tls.spec.js
index 3b0e18197a..e3c758285b 100644
--- a/test/tls.spec.js
+++ b/test/tls.spec.js
@@ -110,17 +110,17 @@ describe('TLS connection tests', function () {
});
describe('using rediss as url protocol', function (done) {
- var tls_connect = tls.connect
+ var tls_connect = tls.connect;
beforeEach(function () {
tls.connect = function (options) {
- options = utils.clone(options)
+ options = utils.clone(options);
options.ca = tls_options.ca;
return tls_connect.call(tls, options);
- }
- })
+ };
+ });
afterEach(function () {
tls.connect = tls_connect;
- })
+ });
it('connect with tls when rediss is used as the protocol', function (done) {
if (skip) this.skip();
client = redis.createClient('rediss://localhost:' + tls_port);
@@ -129,7 +129,7 @@ describe('TLS connection tests', function () {
client.set('foo', 'bar');
client.get('foo', helper.isString('bar', done));
});
- })
+ });
it('fails to connect because the cert is not correct', function (done) {
if (skip) this.skip();
From 12265a5079a133d2003bef9cdb0f2deee0251518 Mon Sep 17 00:00:00 2001
From: Bryan English
Date: Tue, 17 Jul 2018 20:48:48 -0700
Subject: [PATCH 33/96] Remove clientError handler
This event is never emitted on net.Socket or tls.TLSSocket streams in
any of the supported versions of Node.js.
---
index.js | 6 ------
1 file changed, 6 deletions(-)
diff --git a/index.js b/index.js
index ae0848cd62..c43203a7f6 100644
--- a/index.js
+++ b/index.js
@@ -283,12 +283,6 @@ RedisClient.prototype.create_stream = function () {
self.on_error(err);
});
- /* istanbul ignore next: difficult to test and not important as long as we keep this listener */
- this.stream.on('clientError', function (err) {
- debug('clientError occured');
- self.on_error(err);
- });
-
this.stream.once('close', function (hadError) {
self.connection_gone('close');
});
From f384e8630203a479c55a89054f37b71394169a84 Mon Sep 17 00:00:00 2001
From: Mario de Frutos Dieguez
Date: Tue, 7 May 2019 22:50:25 +0200
Subject: [PATCH 34/96] Added timestamp to debug traces (#1426)
* Added timestamp to debug traces
* Make it compatible with node 0.10 and 0.12
---
lib/debug.js | 4 +++-
test/commands/blpop.spec.js | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/debug.js b/lib/debug.js
index 0e6333f2ec..d69c1ea624 100644
--- a/lib/debug.js
+++ b/lib/debug.js
@@ -4,7 +4,9 @@ var index = require('../');
function debug () {
if (index.debug_mode) {
- console.error.apply(null, arguments);
+ var data = Array.prototype.slice.call(arguments);
+ data.unshift(new Date().toISOString());
+ console.error.apply(null, data);
}
}
diff --git a/test/commands/blpop.spec.js b/test/commands/blpop.spec.js
index d68521e6b5..e8d3f59aab 100644
--- a/test/commands/blpop.spec.js
+++ b/test/commands/blpop.spec.js
@@ -31,7 +31,7 @@ describe("The 'blpop' method", function () {
});
client.rpush('blocking list', 'initial value', helper.isNumber(1));
unhookIntercept();
- assert(/^Send 127\.0\.0\.1:6379 id [0-9]+: \*3\r\n\$5\r\nrpush\r\n\$13\r\nblocking list\r\n\$13\r\ninitial value\r\n\n$/.test(text));
+ assert(/Send 127\.0\.0\.1:6379 id [0-9]+: \*3\r\n\$5\r\nrpush\r\n\$13\r\nblocking list\r\n\$13\r\ninitial value\r\n\n$/.test(text));
redis.debug_mode = false;
bclient.blpop('blocking list', 0, function (err, value) {
assert.strictEqual(value[0], 'blocking list');
From a60261da0461d4bb114b1533fada87e97fa985c8 Mon Sep 17 00:00:00 2001
From: Arun Raghavan
Date: Tue, 7 May 2019 20:51:11 +0000
Subject: [PATCH 35/96] Update to recent redis-commands (#1425)
This includes commands from Redis 5.0, including streams-related API.
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index c4e722ac01..4ec213335e 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
},
"dependencies": {
"denque": "^1.2.3",
- "redis-commands": "^1.2.0",
+ "redis-commands": "^1.4.0",
"redis-parser": "^2.6.0"
},
"engines": {
From 87e382a1df6b829a804f574571014e61d4c53566 Mon Sep 17 00:00:00 2001
From: medifle <13296643+medifle@users.noreply.github.com>
Date: Mon, 3 Feb 2020 08:59:34 -0500
Subject: [PATCH 36/96] docs(*): fix async function syntax error (#1490)
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index b208915991..329d046653 100644
--- a/README.md
+++ b/README.md
@@ -74,7 +74,7 @@ return getAsync('foo').then(function(res) {
or using [async await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function):
```js
-async myFunc() {
+async function myFunc() {
const res = await getAsync('foo');
console.log(res);
}
From 1f082aca54f191f5aacf12ab95d01597cc95d4fa Mon Sep 17 00:00:00 2001
From: German Capuano
Date: Mon, 3 Feb 2020 09:45:00 -0500
Subject: [PATCH 37/96] docs(*): additional clarification of Pub/Sub section
(#1489)
The previous phrasing wasn't clear to me. The oxford comma is necessary to avoid ambiguity.
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 329d046653..91695a8b8b 100644
--- a/README.md
+++ b/README.md
@@ -532,8 +532,8 @@ sub.subscribe("a nice channel");
```
When a client issues a `SUBSCRIBE` or `PSUBSCRIBE`, that connection is put into
-a "subscriber" mode. At that point, only commands that modify the subscription
-set are valid and quit (and depending on the redis version ping as well). When
+a "subscriber" mode. At that point, the only valid commands are those that modify the subscription
+set, and quit (also ping on some redis versions). When
the subscription set is empty, the connection is put back into regular mode.
If you need to send regular commands to Redis while in subscriber mode, just
From 78936ac50c43ceb74654501a5da4b2994efe1217 Mon Sep 17 00:00:00 2001
From: Vissarut Tantiwattanarom
Date: Mon, 3 Feb 2020 21:53:56 +0400
Subject: [PATCH 38/96] feat(parser): update to latest Redis parser & errors
(#1470)
* Update redis errors and redis parser
* Fix lint errors
* Add node 12 to travis ci
* Add appveyor node 12
* Fix some of existing errors
This drops support for hiredis.
---
.travis.yml | 1 +
appveyor.yml | 1 +
benchmarks/diff_multi_bench_output.js | 2 +-
examples/streams.js | 74 +++++++++++++--------------
index.js | 7 +--
lib/customErrors.js | 3 +-
package.json | 3 +-
test/node_redis.spec.js | 2 +-
test/rename.spec.js | 4 +-
9 files changed, 50 insertions(+), 47 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index f2422e979b..09398ddac0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,6 +14,7 @@ node_js:
- "4"
- "6"
- "8"
+ - "12"
after_success: npm run coveralls
before_script:
# Add an IPv6 config - see the corresponding Travis issue
diff --git a/appveyor.yml b/appveyor.yml
index 7930f05f8a..e3d2c2a940 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -8,6 +8,7 @@ environment:
- nodejs_version: "4"
- nodejs_version: "6"
- nodejs_version: "8"
+ - nodejs_version: "12"
pull_requests:
do_not_increment_build_number: true
diff --git a/benchmarks/diff_multi_bench_output.js b/benchmarks/diff_multi_bench_output.js
index dc0d3c227d..c3ed47a5fb 100755
--- a/benchmarks/diff_multi_bench_output.js
+++ b/benchmarks/diff_multi_bench_output.js
@@ -2,7 +2,7 @@
var fs = require('fs');
var metrics = require('metrics');
- // `node diff_multi_bench_output.js beforeBench.txt afterBench.txt`
+// `node diff_multi_bench_output.js beforeBench.txt afterBench.txt`
var file1 = process.argv[2];
var file2 = process.argv[3];
diff --git a/examples/streams.js b/examples/streams.js
index 2fda1293ce..726e4adf92 100644
--- a/examples/streams.js
+++ b/examples/streams.js
@@ -5,43 +5,43 @@ var client1 = redis.createClient();
var client2 = redis.createClient();
var client3 = redis.createClient();
-client1.xadd('mystream', '*', 'field1', 'm1', function (err) {
- if(err){
- return console.error(err);
- }
- client1.xgroup('CREATE', 'mystream', 'mygroup', '$', function (err) {
- if(err){
- return console.error(err);
- }
- });
-
- client2.xreadgroup('GROUP', 'mygroup', 'consumer', 'Block', 1000, 'NOACK',
- 'STREAMS', 'mystream', '>', function (err, stream) {
- if(err){
- return console.error(err);
- }
- console.log('client2 ' + stream);
- });
-
- client3.xreadgroup('GROUP', 'mygroup', 'consumer', 'Block', 1000, 'NOACK',
- 'STREAMS', 'mystream', '>', function (err, stream) {
- if(err){
- return console.error(err);
- }
- console.log('client3 ' + stream);
- });
+client1.xadd('mystream', '*', 'field1', 'm1', function (err) {
+ if (err) {
+ return console.error(err);
+ }
+ client1.xgroup('CREATE', 'mystream', 'mygroup', '$', function (err) {
+ if (err) {
+ return console.error(err);
+ }
+ });
-
- client1.xadd('mystream', '*', 'field1', 'm2', function (err) {
- if(err){
- return console.error(err);
- }
- });
-
- client1.xadd('mystream', '*', 'field1', 'm3', function (err) {
- if(err){
- return console.error(err);
- }
- });
+ client2.xreadgroup('GROUP', 'mygroup', 'consumer', 'Block', 1000, 'NOACK',
+ 'STREAMS', 'mystream', '>', function (err, stream) {
+ if (err) {
+ return console.error(err);
+ }
+ console.log('client2 ' + stream);
+ });
+
+ client3.xreadgroup('GROUP', 'mygroup', 'consumer', 'Block', 1000, 'NOACK',
+ 'STREAMS', 'mystream', '>', function (err, stream) {
+ if (err) {
+ return console.error(err);
+ }
+ console.log('client3 ' + stream);
+ });
+
+
+ client1.xadd('mystream', '*', 'field1', 'm2', function (err) {
+ if (err) {
+ return console.error(err);
+ }
+ });
+
+ client1.xadd('mystream', '*', 'field1', 'm3', function (err) {
+ if (err) {
+ return console.error(err);
+ }
+ });
});
diff --git a/index.js b/index.js
index c43203a7f6..402b9b1e47 100644
--- a/index.js
+++ b/index.js
@@ -9,6 +9,7 @@ var Queue = require('denque');
var errorClasses = require('./lib/customErrors');
var EventEmitter = require('events');
var Parser = require('redis-parser');
+var RedisErrors = require('redis-errors');
var commands = require('redis-commands');
var debug = require('./lib/debug');
var unifyOptions = require('./lib/createClient');
@@ -1090,9 +1091,9 @@ exports.RedisClient = RedisClient;
exports.print = utils.print;
exports.Multi = require('./lib/multi');
exports.AbortError = errorClasses.AbortError;
-exports.RedisError = Parser.RedisError;
-exports.ParserError = Parser.ParserError;
-exports.ReplyError = Parser.ReplyError;
+exports.RedisError = RedisErrors.RedisError;
+exports.ParserError = RedisErrors.ParserError;
+exports.ReplyError = RedisErrors.ReplyError;
exports.AggregateError = errorClasses.AggregateError;
// Add all redis commands / node_redis api to the client
diff --git a/lib/customErrors.js b/lib/customErrors.js
index d9b34421a7..2483db0d8d 100644
--- a/lib/customErrors.js
+++ b/lib/customErrors.js
@@ -2,14 +2,13 @@
var util = require('util');
var assert = require('assert');
-var RedisError = require('redis-parser').RedisError;
+var RedisError = require('redis-errors').RedisError;
var ADD_STACKTRACE = false;
function AbortError (obj, stack) {
assert(obj, 'The options argument is required');
assert.strictEqual(typeof obj, 'object', 'The options argument has to be of type object');
- RedisError.call(this, obj.message, ADD_STACKTRACE);
Object.defineProperty(this, 'message', {
value: obj.message || '',
configurable: true,
diff --git a/package.json b/package.json
index 4ec213335e..d294765fc9 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,8 @@
"dependencies": {
"denque": "^1.2.3",
"redis-commands": "^1.4.0",
- "redis-parser": "^2.6.0"
+ "redis-errors": "^1.2.0",
+ "redis-parser": "^3.0.0"
},
"engines": {
"node": ">=0.10.0"
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index e553f8521e..82b3e4e09f 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -359,7 +359,7 @@ describe('The node_redis client', function () {
it('send_command with callback as args', function (done) {
client.send_command('abcdef', function (err, res) {
- assert.strictEqual(err.message, "ERR unknown command 'abcdef'");
+ assert.strictEqual(err.message, 'ERR unknown command `abcdef`, with args beginning with: ');
done();
});
});
diff --git a/test/rename.spec.js b/test/rename.spec.js
index b98661e9f5..b8f7c65d0d 100644
--- a/test/rename.spec.js
+++ b/test/rename.spec.js
@@ -50,7 +50,7 @@ describe('rename commands', function () {
});
client.get('key', function (err, reply) {
- assert.strictEqual(err.message, "ERR unknown command 'get'");
+ assert.strictEqual(err.message, 'ERR unknown command `get`, with args beginning with: `key`, ');
assert.strictEqual(err.command, 'GET');
assert.strictEqual(reply, undefined);
});
@@ -108,7 +108,7 @@ describe('rename commands', function () {
multi.exec(function (err, res) {
assert(err);
assert.strictEqual(err.message, 'EXECABORT Transaction discarded because of previous errors.');
- assert.strictEqual(err.errors[0].message, "ERR unknown command 'get'");
+ assert.strictEqual(err.errors[0].message, 'ERR unknown command `get`, with args beginning with: `key`, ');
assert.strictEqual(err.errors[0].command, 'GET');
assert.strictEqual(err.code, 'EXECABORT');
assert.strictEqual(err.errors[0].code, 'ERR');
From 1f5555d96eedecf7995e3928748533f992c15450 Mon Sep 17 00:00:00 2001
From: "Indospace.io"
Date: Mon, 3 Feb 2020 09:57:59 -0800
Subject: [PATCH 39/96] feat(commands): update redis-commands version (#1454)
update redis-commands and redis-parser
Co-authored-by: Mike Diarmid
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index d294765fc9..827083920e 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
},
"dependencies": {
"denque": "^1.2.3",
- "redis-commands": "^1.4.0",
+ "redis-commands": "^1.5.0",
"redis-errors": "^1.2.0",
"redis-parser": "^3.0.0"
},
From c78e55d874dc1a791ee75d02b30196a01d9202a4 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 21:25:28 +0000
Subject: [PATCH 40/96] tests: use stream timeout property instead of internal
property
fixes broken test
---
test/connection.spec.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/connection.spec.js b/test/connection.spec.js
index c33d1b8a83..f467f19578 100644
--- a/test/connection.spec.js
+++ b/test/connection.spec.js
@@ -401,10 +401,10 @@ describe('connection tests', function () {
connect_timeout: 1000
});
process.nextTick(function () {
- assert.strictEqual(client.stream._idleTimeout, 1000);
+ assert.strictEqual(client.stream.timeout, 1000);
});
client.on('connect', function () {
- assert.strictEqual(client.stream._idleTimeout, -1);
+ assert.strictEqual(client.stream.timeout, 0);
assert.strictEqual(client.stream.listeners('timeout').length, 0);
client.on('ready', done);
});
From fbdac9e0ad338e730445116daabdde1893f9f7ba Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 21:26:53 +0000
Subject: [PATCH 41/96] tests: remove hiredis from testing suite
as parser no longer supports hiredis
---
test/helper.js | 5 -----
test/pubsub.spec.js | 8 ++------
2 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/test/helper.js b/test/helper.js
index e851b7f7b3..29a07d6f31 100644
--- a/test/helper.js
+++ b/test/helper.js
@@ -163,11 +163,6 @@ module.exports = {
}
var parsers = ['javascript'];
var protocols = ['IPv4'];
- // The js parser works the same as the hiredis parser, just activate this if you want to be on the safe side
- // try {
- // require('hiredis');
- // parsers.push('hiredis');
- // } catch (e) {/* ignore eslint */}
if (process.platform !== 'win32') {
protocols.push('IPv6', '/tmp/redis.sock');
}
diff --git a/test/pubsub.spec.js b/test/pubsub.spec.js
index 94b0fc1880..c017cdb36f 100644
--- a/test/pubsub.spec.js
+++ b/test/pubsub.spec.js
@@ -515,8 +515,8 @@ describe('publish/subscribe', function () {
sub.stream.once('data', function () {
assert.strictEqual(sub.message_buffers, false);
assert.strictEqual(sub.shouldBuffer, false);
- sub.on('pmessageBuffer', function (pattern, channel, message) {
- if (parser !== 'javascript' && typeof pattern === 'string') {
+ sub.on('pmessageBuffer', function (pattern, channel) {
+ if (typeof pattern === 'string') {
pattern = new Buffer(pattern);
channel = new Buffer(channel);
}
@@ -524,10 +524,6 @@ describe('publish/subscribe', function () {
assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect());
sub.quit(end);
});
- if (parser === 'javascript') {
- assert.notStrictEqual(sub.message_buffers, sub.buffers);
- }
-
});
var batch = sub.batch();
batch.psubscribe('*');
From 7c551bf4741b97bf5d67271b5a20bc2829cbfb76 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 21:27:49 +0000
Subject: [PATCH 42/96] tests: fix tls tests and enable stunnel tests for
travis
---
test/tls.spec.js | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/test/tls.spec.js b/test/tls.spec.js
index e3c758285b..127a2cfb8d 100644
--- a/test/tls.spec.js
+++ b/test/tls.spec.js
@@ -19,9 +19,6 @@ var tls_port = 6380;
// Use skip instead of returning to indicate what tests really got skipped
var skip = false;
-// Wait until stunnel4 is in the travis whitelist
-// Check: https://github.com/travis-ci/apt-package-whitelist/issues/403
-// If this is merged, remove the travis env checks
describe('TLS connection tests', function () {
before(function (done) {
@@ -29,9 +26,6 @@ describe('TLS connection tests', function () {
if (process.platform === 'win32') {
skip = true;
console.warn('\nStunnel tests do not work on windows atm. If you think you can fix that, it would be warmly welcome.\n');
- } else if (process.env.TRAVIS === 'true') {
- skip = true;
- console.warn('\nTravis does not support stunnel right now. Skipping tests.\nCheck: https://github.com/travis-ci/apt-package-whitelist/issues/403\n');
}
if (skip) return done();
helper.stopStunnel(function () {
@@ -58,7 +52,7 @@ describe('TLS connection tests', function () {
client = redis.createClient({
connect_timeout: connect_timeout,
port: tls_port,
- tls: tls_options
+ tls: utils.clone(tls_options)
});
var time = 0;
assert.strictEqual(client.address, '127.0.0.1:' + tls_port);
@@ -109,12 +103,14 @@ describe('TLS connection tests', function () {
client.get('foo', helper.isString('bar', done));
});
- describe('using rediss as url protocol', function (done) {
+ describe('using rediss as url protocol', function () {
var tls_connect = tls.connect;
beforeEach(function () {
tls.connect = function (options) {
options = utils.clone(options);
options.ca = tls_options.ca;
+ options.servername = 'redis.js.org';
+ options.rejectUnauthorized = true;
return tls_connect.call(tls, options);
};
});
From a4fec3c361f513f57bdd5b7ce0fa0a96c03c9260 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 21:29:02 +0000
Subject: [PATCH 43/96] tests(travis): drop < node v4, add v13 & install
stunnel
---
.travis.yml | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 09398ddac0..0248be673f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,12 +9,18 @@ addons:
packages:
- g++-4.8
node_js:
- - "0.10"
- - "0.12"
- "4"
- "6"
- "8"
- "12"
+ - "13"
+
+before_install:
+ - if [[ ! -f downloads/stunnel-5.54.tar.gz ]]; then wget -O downloads/stunnel-5.54.tar.gz ftp://ftp.stunnel.org/stunnel/archive/5.x/stunnel-5.54.tar.gz; fi
+ - if [[ ! -f ./stunnel-5.54/configure ]]; then tar -xzf downloads/stunnel-5.54.tar.gz; fi
+ - if [[ ! -f ./stunnel-5.54/src/stunnel ]]; then cd ./stunnel-5.54; ./configure; make; cd ..; fi
+ - export PATH="$PATH:$(pwd)/stunnel-5.54/src"
+
after_success: npm run coveralls
before_script:
# Add an IPv6 config - see the corresponding Travis issue
From 17c12339887c4dce5b96e073e48105c4f83076bd Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 21:30:15 +0000
Subject: [PATCH 44/96] tests(appveyor): drop < node v4 & add v13
---
appveyor.yml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/appveyor.yml b/appveyor.yml
index e3d2c2a940..42155ac1d2 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -3,12 +3,11 @@
# Test against these versions of Node.js.
environment:
matrix:
- - nodejs_version: "0.10"
- - nodejs_version: "0.12"
- nodejs_version: "4"
- nodejs_version: "6"
- nodejs_version: "8"
- nodejs_version: "12"
+ - nodejs_version: "13"
pull_requests:
do_not_increment_build_number: true
From 694154b377f1ad8e2bcbd67d846301e0275627e6 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 21:33:03 +0000
Subject: [PATCH 45/96] chore: add IDE files to .gitignore
---
.gitignore | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/.gitignore b/.gitignore
index 2290a8ec51..43529fa00b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,14 @@ coverage
stunnel.conf
stunnel.pid
*.out
+package-lock.json
+
+# IntelliJ IDEs
+.idea
+
+# VisualStudioCode IDEs
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
From 0adcb738014b969de9b7bdd4e977cab7693667ef Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 21:45:34 +0000
Subject: [PATCH 46/96] tests(travis): cache stunnel install
---
.travis.yml | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 0248be673f..e0c8e7d152 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,11 +16,15 @@ node_js:
- "13"
before_install:
- - if [[ ! -f downloads/stunnel-5.54.tar.gz ]]; then wget -O downloads/stunnel-5.54.tar.gz ftp://ftp.stunnel.org/stunnel/archive/5.x/stunnel-5.54.tar.gz; fi
- - if [[ ! -f ./stunnel-5.54/configure ]]; then tar -xzf downloads/stunnel-5.54.tar.gz; fi
+ - if [[ ! -f stunnel.tar.gz ]]; then wget -O stunnel.tar.gz ftp://ftp.stunnel.org/stunnel/archive/5.x/stunnel-5.54.tar.gz; fi
+ - if [[ ! -f ./stunnel-5.54/configure ]]; then tar -xzf stunnel.tar.gz; fi
- if [[ ! -f ./stunnel-5.54/src/stunnel ]]; then cd ./stunnel-5.54; ./configure; make; cd ..; fi
- export PATH="$PATH:$(pwd)/stunnel-5.54/src"
+cache:
+ directories:
+ - '$TRAVIS_BUILD_DIR/stunnel-5.54'
+
after_success: npm run coveralls
before_script:
# Add an IPv6 config - see the corresponding Travis issue
From 5be0d3a78e93daa6cdd227a6d079c534cc162a47 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 22:00:11 +0000
Subject: [PATCH 47/96] chore: update .gitignore
---
.gitignore | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/.gitignore b/.gitignore
index 43529fa00b..037016a27f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,10 +11,6 @@ package-lock.json
# IntelliJ IDEs
.idea
-
# VisualStudioCode IDEs
-.vscode/*
-!.vscode/settings.json
-!.vscode/tasks.json
-!.vscode/launch.json
-!.vscode/extensions.json
+.vscode
+.vs
From 031e00f22e8672e152d8f2bc58968a940840bbf9 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 22:13:22 +0000
Subject: [PATCH 48/96] tests: fix socket timeout test Node <= 4
---
test/connection.spec.js | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/test/connection.spec.js b/test/connection.spec.js
index f467f19578..f6dc8310cb 100644
--- a/test/connection.spec.js
+++ b/test/connection.spec.js
@@ -401,10 +401,22 @@ describe('connection tests', function () {
connect_timeout: 1000
});
process.nextTick(function () {
- assert.strictEqual(client.stream.timeout, 1000);
+ // node > 4
+ var timeout = client.stream.timeout;
+ // node <= 4
+ if (timeout === undefined) timeout = client.stream._idleTimeout;
+ assert.strictEqual(timeout, 1000);
});
client.on('connect', function () {
- assert.strictEqual(client.stream.timeout, 0);
+ // node > 4
+ var expected = 0;
+ var timeout = client.stream.timeout;
+ // node <= 4
+ if (timeout === undefined) {
+ timeout = client.stream._idleTimeout;
+ expected = -1;
+ }
+ assert.strictEqual(timeout, expected);
assert.strictEqual(client.stream.listeners('timeout').length, 0);
client.on('ready', done);
});
From 36b62fe5792ee4f33a58ad7f8916e708e0bd0b1d Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 22:26:55 +0000
Subject: [PATCH 49/96] tests: fix error codes test Node >= 13
---
test/node_redis.spec.js | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index 82b3e4e09f..a6504ddf2b 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -986,7 +986,14 @@ describe('The node_redis client', function () {
}
} else {
assert.equal(err.code, 'ECONNREFUSED');
- assert.equal(err.errno, 'ECONNREFUSED');
+
+ if (typeof err.errno === 'number') {
+ // >= Node 13
+ assert.equal(err.errno, -61);
+ } else {
+ // < Node 13
+ assert.equal(err.errno, 'ECONNREFUSED');
+ }
assert.equal(err.syscall, 'connect');
}
});
From 13ec6afe5802cfd426cc411b74d4ac0a22b3e3e1 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Thu, 6 Feb 2020 23:59:31 +0000
Subject: [PATCH 50/96] tests: fix Error & Domain tests on Node >= 13
---
test/node_redis.spec.js | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index a6504ddf2b..d23cd7b81c 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -675,15 +675,21 @@ describe('The node_redis client', function () {
done();
});
});
- require('domain').create();
});
it('catches all errors from within the domain', function (done) {
var domain = require('domain').create();
domain.run(function () {
- // Trigger an error within the domain
+ if (process.versions.node.split('.')[0] >= 13) {
+ // Node >= 13
+ // Recreate client in domain so error handlers run this domain
+ // Changed in: "error handler runs outside of its domain"
+ // https://github.com/nodejs/node/pull/26211
+ client = redis.createClient();
+ }
client.end(true);
+ // Trigger an error within the domain
client.set('domain', 'value');
});
@@ -1053,7 +1059,13 @@ describe('The node_redis client', function () {
end();
} else {
assert.equal(err.code, 'ECONNREFUSED');
- assert.equal(err.errno, 'ECONNREFUSED');
+ if (typeof err.errno === 'number') {
+ // >= Node 13
+ assert.equal(err.errno, -61);
+ } else {
+ // < Node 13
+ assert.equal(err.errno, 'ECONNREFUSED');
+ }
assert.equal(err.syscall, 'connect');
end();
}
@@ -1139,7 +1151,13 @@ describe('The node_redis client', function () {
end();
} else {
assert.equal(err.code, 'ECONNREFUSED');
- assert.equal(err.errno, 'ECONNREFUSED');
+ if (typeof err.errno === 'number') {
+ // >= Node 13
+ assert.equal(err.errno, -61);
+ } else {
+ // < Node 13
+ assert.equal(err.errno, 'ECONNREFUSED');
+ }
assert.equal(err.syscall, 'connect');
redis.debug_mode = false;
client.end(true);
From 9d65e1c3ededcf3f266ddab0a509a47432dc7ddc Mon Sep 17 00:00:00 2001
From: Salakar
Date: Fri, 7 Feb 2020 00:31:08 +0000
Subject: [PATCH 51/96] tests: fix buffer test (failed due to new parser) &
remove unused node feature checks (< 4)
---
index.js | 12 ------------
lib/commands.js | 28 ++++++----------------------
test/pubsub.spec.js | 2 ++
3 files changed, 8 insertions(+), 34 deletions(-)
diff --git a/index.js b/index.js
index 402b9b1e47..b1f265262c 100644
--- a/index.js
+++ b/index.js
@@ -20,11 +20,6 @@ var SUBSCRIBE_COMMANDS = {
punsubscribe: true
};
-// Newer Node.js versions > 0.10 return the EventEmitter right away and using .EventEmitter was deprecated
-if (typeof EventEmitter !== 'function') {
- EventEmitter = EventEmitter.EventEmitter;
-}
-
function noop () {}
function handle_detect_buffers_reply (reply, command, buffer_args) {
@@ -153,7 +148,6 @@ function RedisClient (options, stream) {
this.server_info = {};
this.auth_pass = options.auth_pass || options.password;
this.selected_db = options.db; // Save the selected db here, used when reconnecting
- this.old_state = null;
this.fire_strings = true; // Determine if strings or buffers should be written to the stream
this.pipeline = false;
this.sub_commands_left = 0;
@@ -175,12 +169,6 @@ function RedisClient (options, stream) {
'If you want to keep on listening to this event please listen to the stream drain event directly.'
);
} else if ((event === 'message_buffer' || event === 'pmessage_buffer' || event === 'messageBuffer' || event === 'pmessageBuffer') && !this.buffers && !this.message_buffers) {
- if (this.reply_parser.name !== 'javascript') {
- return this.warn(
- 'You attached the "' + event + '" listener without the returnBuffers option set to true.\n' +
- 'Please use the JavaScript parser or set the returnBuffers option to true to return buffers.'
- );
- }
this.reply_parser.optionReturnBuffers = true;
this.message_buffers = true;
this.handle_reply = handle_detect_buffers_reply;
diff --git a/lib/commands.js b/lib/commands.js
index 6275ec8bf6..a3b5189698 100644
--- a/lib/commands.js
+++ b/lib/commands.js
@@ -4,18 +4,6 @@ var commands = require('redis-commands');
var Multi = require('./multi');
var RedisClient = require('../').RedisClient;
var Command = require('./command');
-// Feature detect if a function may change it's name
-var changeFunctionName = (function () {
- var fn = function abc () {};
- try {
- Object.defineProperty(fn, 'name', {
- value: 'foobar'
- });
- return true;
- } catch (e) {
- return false;
- }
-}());
var addCommand = function (command) {
// Some rare Redis commands use special characters in their command name
@@ -61,11 +49,9 @@ var addCommand = function (command) {
if (commandName !== command) {
RedisClient.prototype[commandName.toUpperCase()] = RedisClient.prototype[commandName] = RedisClient.prototype[command];
}
- if (changeFunctionName) {
- Object.defineProperty(RedisClient.prototype[command], 'name', {
- value: commandName
- });
- }
+ Object.defineProperty(RedisClient.prototype[command], 'name', {
+ value: commandName
+ });
}
// Do not override existing functions
@@ -108,11 +94,9 @@ var addCommand = function (command) {
if (commandName !== command) {
Multi.prototype[commandName.toUpperCase()] = Multi.prototype[commandName] = Multi.prototype[command];
}
- if (changeFunctionName) {
- Object.defineProperty(Multi.prototype[command], 'name', {
- value: commandName
- });
- }
+ Object.defineProperty(Multi.prototype[command], 'name', {
+ value: commandName
+ });
}
};
diff --git a/test/pubsub.spec.js b/test/pubsub.spec.js
index c017cdb36f..da2561459f 100644
--- a/test/pubsub.spec.js
+++ b/test/pubsub.spec.js
@@ -524,6 +524,8 @@ describe('publish/subscribe', function () {
assert.strictEqual(channel.inspect(), new Buffer('/foo').inspect());
sub.quit(end);
});
+ // Either message_buffers or buffers has to be true, but not both at the same time
+ assert.notStrictEqual(sub.message_buffers, sub.buffers);
});
var batch = sub.batch();
batch.psubscribe('*');
From 9e3b57eae7f8a1d0668ee7645e8180f79fc6e349 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Fri, 7 Feb 2020 00:54:52 +0000
Subject: [PATCH 52/96] tests: use util.getSystemErrorName for errno
---
index.js | 1 -
test/node_redis.spec.js | 7 ++++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/index.js b/index.js
index b1f265262c..b5acf785eb 100644
--- a/index.js
+++ b/index.js
@@ -204,7 +204,6 @@ function create_parser (self) {
self.create_stream();
},
returnBuffers: self.buffers || self.message_buffers,
- name: self.options.parser || 'javascript',
stringNumbers: self.options.string_numbers || false
});
}
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index d23cd7b81c..22bd74463c 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -2,6 +2,7 @@
var assert = require('assert');
var fs = require('fs');
+var util = require('util');
var path = require('path');
var intercept = require('intercept-stdout');
var config = require('./lib/config');
@@ -995,7 +996,7 @@ describe('The node_redis client', function () {
if (typeof err.errno === 'number') {
// >= Node 13
- assert.equal(err.errno, -61);
+ assert.equal(err.errno, util.getSystemErrorName(err.errno));
} else {
// < Node 13
assert.equal(err.errno, 'ECONNREFUSED');
@@ -1061,7 +1062,7 @@ describe('The node_redis client', function () {
assert.equal(err.code, 'ECONNREFUSED');
if (typeof err.errno === 'number') {
// >= Node 13
- assert.equal(err.errno, -61);
+ assert.equal(err.errno, util.getSystemErrorName(err.errno));
} else {
// < Node 13
assert.equal(err.errno, 'ECONNREFUSED');
@@ -1153,7 +1154,7 @@ describe('The node_redis client', function () {
assert.equal(err.code, 'ECONNREFUSED');
if (typeof err.errno === 'number') {
// >= Node 13
- assert.equal(err.errno, -61);
+ assert.equal(err.errno, util.getSystemErrorName(err.errno));
} else {
// < Node 13
assert.equal(err.errno, 'ECONNREFUSED');
From 9220016c7d70b0bfebd4bbeb890396f5fe4b2b0a Mon Sep 17 00:00:00 2001
From: Salakar
Date: Fri, 7 Feb 2020 01:06:47 +0000
Subject: [PATCH 53/96] tests: use util.getSystemErrorName for errno
---
test/node_redis.spec.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index 22bd74463c..317723f56a 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -996,7 +996,7 @@ describe('The node_redis client', function () {
if (typeof err.errno === 'number') {
// >= Node 13
- assert.equal(err.errno, util.getSystemErrorName(err.errno));
+ assert.equal(util.getSystemErrorName(err.errno), 'ECONNREFUSED');
} else {
// < Node 13
assert.equal(err.errno, 'ECONNREFUSED');
@@ -1062,7 +1062,7 @@ describe('The node_redis client', function () {
assert.equal(err.code, 'ECONNREFUSED');
if (typeof err.errno === 'number') {
// >= Node 13
- assert.equal(err.errno, util.getSystemErrorName(err.errno));
+ assert.equal(util.getSystemErrorName(err.errno), 'ECONNREFUSED');
} else {
// < Node 13
assert.equal(err.errno, 'ECONNREFUSED');
@@ -1154,7 +1154,7 @@ describe('The node_redis client', function () {
assert.equal(err.code, 'ECONNREFUSED');
if (typeof err.errno === 'number') {
// >= Node 13
- assert.equal(err.errno, util.getSystemErrorName(err.errno));
+ assert.equal(util.getSystemErrorName(err.errno), 'ECONNREFUSED');
} else {
// < Node 13
assert.equal(err.errno, 'ECONNREFUSED');
From 6ce845f620bc5b0aa6d4704492fe27365347d60f Mon Sep 17 00:00:00 2001
From: Salakar
Date: Fri, 7 Feb 2020 01:23:17 +0000
Subject: [PATCH 54/96] chore: set package min node version to >=v4
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 827083920e..3cedc98b8f 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,7 @@
"redis-parser": "^3.0.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=4.0.0"
},
"devDependencies": {
"bluebird": "^3.0.2",
From caaae9c97f8756b0c476b5467613ba126e9f17c7 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Fri, 7 Feb 2020 01:24:25 +0000
Subject: [PATCH 55/96] chore: update denque to v1.4.1
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 3cedc98b8f..015b93a8c7 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
"compare": "node benchmarks/diff_multi_bench_output.js beforeBench.txt afterBench.txt"
},
"dependencies": {
- "denque": "^1.2.3",
+ "denque": "^1.4.1",
"redis-commands": "^1.5.0",
"redis-errors": "^1.2.0",
"redis-parser": "^3.0.0"
From 3569a68f5df7df910e9b3961f3bd66fb49ba3210 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Fri, 7 Feb 2020 01:46:35 +0000
Subject: [PATCH 56/96] tests: fix test on windows
---
test/node_redis.spec.js | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index 317723f56a..a77c5146a8 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -360,7 +360,11 @@ describe('The node_redis client', function () {
it('send_command with callback as args', function (done) {
client.send_command('abcdef', function (err, res) {
- assert.strictEqual(err.message, 'ERR unknown command `abcdef`, with args beginning with: ');
+ if (process.platform === 'win32') {
+ assert.strictEqual(err.message, 'ERR unknown command `abcdef`');
+ } else {
+ assert.strictEqual(err.message, 'ERR unknown command `abcdef`, with args beginning with: ');
+ }
done();
});
});
From feb4652ad246c488498dd1d0371981354c0a751a Mon Sep 17 00:00:00 2001
From: Salakar
Date: Fri, 7 Feb 2020 01:48:23 +0000
Subject: [PATCH 57/96] tests: disable node > 12 tests on windows, nyc fails to
launch
nyc needs upgrading to v15, but v15 only works in node versions that support let/const
---
appveyor.yml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/appveyor.yml b/appveyor.yml
index 42155ac1d2..d9cd4f4b63 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -6,8 +6,9 @@ environment:
- nodejs_version: "4"
- nodejs_version: "6"
- nodejs_version: "8"
- - nodejs_version: "12"
- - nodejs_version: "13"
+ - nodejs_version: "10"
+# - nodejs_version: "12"
+# - nodejs_version: "13"
pull_requests:
do_not_increment_build_number: true
From 1d8fa45689faded4b4ae8ebf70cbb3813dce477f Mon Sep 17 00:00:00 2001
From: Mike Diarmid
Date: Fri, 7 Feb 2020 02:01:52 +0000
Subject: [PATCH 58/96] tests: fix windows text
---
test/node_redis.spec.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index a77c5146a8..d529d40da3 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -361,7 +361,7 @@ describe('The node_redis client', function () {
it('send_command with callback as args', function (done) {
client.send_command('abcdef', function (err, res) {
if (process.platform === 'win32') {
- assert.strictEqual(err.message, 'ERR unknown command `abcdef`');
+ assert.strictEqual(err.message, "ERR unknown command 'abcdef'");
} else {
assert.strictEqual(err.message, 'ERR unknown command `abcdef`, with args beginning with: ');
}
From c0cc0bfab44d5ce5fa2fdc5c9af85401c4ff0b5c Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 02:05:21 +0000
Subject: [PATCH 59/96] start of work towards v3 release
---
.github/FUNDING.yml | 1 +
.npmignore | 6 ++
.travis.yml | 1 -
changelog.md => CHANGELOG.md | 29 +++++++
CODE_OF_CONDUCT.md | 46 ++++++++++
CONTRIBUTING.md | 1 +
LICENSE | 6 +-
README.md | 81 +++++-------------
appveyor.yml | 1 -
index.js | 143 +++++++++++--------------------
package.json | 40 ++++++---
test/auth.spec.js | 2 +-
test/commands/hset.spec.js | 18 ++--
test/commands/set.spec.js | 12 ++-
test/connection.spec.js | 67 +++------------
test/lib/redis-process.js | 2 +-
test/multi.spec.js | 20 +++--
test/node_redis.spec.js | 158 ++---------------------------------
18 files changed, 234 insertions(+), 400 deletions(-)
create mode 100644 .github/FUNDING.yml
rename changelog.md => CHANGELOG.md (97%)
create mode 100644 CODE_OF_CONDUCT.md
create mode 100644 CONTRIBUTING.md
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000000..1893f87aad
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+open_collective: node-redis
diff --git a/.npmignore b/.npmignore
index 569f3efb2b..497486e4e0 100644
--- a/.npmignore
+++ b/.npmignore
@@ -11,3 +11,9 @@ coverage/
*.rdb
*.out
*.yml
+CHANGELOG.md
+CONTRIBUTING.md
+CODE_OF_CONDUCT.md
+.travis.yml
+appveyor.yml
+package-lock.json
diff --git a/.travis.yml b/.travis.yml
index e0c8e7d152..d1bd2e3cef 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,7 +9,6 @@ addons:
packages:
- g++-4.8
node_js:
- - "4"
- "6"
- "8"
- "12"
diff --git a/changelog.md b/CHANGELOG.md
similarity index 97%
rename from changelog.md
rename to CHANGELOG.md
index d650f9ba39..daea8eeefc 100644
--- a/changelog.md
+++ b/CHANGELOG.md
@@ -1,5 +1,34 @@
# Changelog
+## v.3.0.0 - 09 Feb, 2020
+
+This version is mainly a release to distribute all the unreleased changes on master since 2017 and additionally removes
+a lot of old deprecated features and old internals in preparation for an upcoming modernization refactor (v4).
+
+### Breaking Changes
+
+ - Dropped support for Node.js < 6
+ - Dropped support for `hiredis` (no longer required)
+ - Removed previously deprecated `drain` event
+ - Removed previously deprecated `idle` event
+ - Removed previously deprecated `parser` option
+ - Removed previously deprecated `max_delay` option
+ - Removed previously deprecated `max_attempts` option
+ - Removed previously deprecated `socket_no_delay` option
+
+### Bug Fixes
+
+ - Removed development files from published package (#1370)
+ - Duplicate function now allows db param to be passed (#1311)
+
+### Features
+
+ - Upgraded to latest `redis-commands` package
+ - Upgraded to latest `redis-parser` package, v3.0.0, which brings performance improvements
+ - Replaced `double-ended-queue` with `denque`, which brings performance improvements
+ - Add timestamps to debug traces
+ - Add `socket_initial_delay` option for `socket.setKeepAlive` (#1396)
+
## v.2.8.0 - 31 Jul, 2017
Features
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000000..00aad77d08
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at `redis @ invertase.io`. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..cf873b4c07
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1 @@
+
diff --git a/LICENSE b/LICENSE
index 710407f442..7b7ba1393b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
-LICENSE - "MIT License"
+MIT License
-Copyright (c) 2016 by NodeRedis
+Copyright (c) Node Redis contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@@ -21,4 +21,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
index 91695a8b8b..e4f60d3ab3 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,21 @@
-redis - a node.js redis client
-===========================
+
+
+
+
+
Node Redis
+ A high performance Node.js Redis client.
+
-[](https://travis-ci.org/NodeRedis/node_redis)
-[](https://coveralls.io/r/NodeRedis/node_redis?branch=)
-[](https://ci.appveyor.com/project/BridgeAR/node-redis/branch/master)
-[](https://gitter.im/NodeRedis/node_redis?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+
+
+
+
+
+
+
+
+
+---
This is a complete and feature rich Redis client for node.js. __It supports all
Redis commands__ and focuses on high performance.
@@ -195,30 +206,11 @@ So please attach the error listener to node_redis.
`client` will emit `end` when an established Redis server connection has closed.
-### "drain" (deprecated)
-
-`client` will emit `drain` when the TCP connection to the Redis server has been
-buffering, but is now writable. This event can be used to stream commands in to
-Redis and adapt to backpressure.
-
-If the stream is buffering `client.should_buffer` is set to true. Otherwise the
-variable is always set to false. That way you can decide when to reduce your
-send rate and resume sending commands when you get `drain`.
-
-You can also check the return value of each command as it will also return the
-backpressure indicator (deprecated). If false is returned the stream had to
-buffer.
-
### "warning"
`client` will emit `warning` when password was set but none is needed and if a
deprecated option / function / similar is used.
-### "idle" (deprecated)
-
-`client` will emit `idle` when there are no outstanding commands that are
-awaiting a response.
-
## redis.createClient()
If you have `redis-server` running on the same machine as node, then the
defaults for port and host are probably fine and you don't need to supply any
@@ -242,17 +234,13 @@ __Note:__ Using `'rediss://...` for the protocol in a `redis_url` will enable a
| port | 6379 | Port of the Redis server |
| path | null | The UNIX socket string of the Redis server |
| url | null | The URL of the Redis server. Format: `[redis[s]:]//[[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)). |
-| 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. |
| 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. |
| return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. |
| 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. |
| socket_keepalive | true | If set to `true`, the keep-alive functionality is enabled on the underlying socket. |
-| socket_initialdelay | 0 | Initial Delay in milliseconds, and this will also behave the interval keep alive message sending to Redis. |
+| socket_initial_delay | 0 | Initial Delay in milliseconds, and this will also behave the interval keep alive message sending to Redis. |
| no_ready_check | false | When a connection is established to the Redis server, the server might still be loading the database from disk. While loading, the server will not respond to any commands. To work around this, `node_redis` has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command indicates whether the server is ready for more commands. When ready, `node_redis` emits a `ready` event. Setting `no_ready_check` to `true` will inhibit this check. |
| enable_offline_queue | true | By default, if there is no active connection to the Redis server, commands are added to a queue and are executed once the connection has been established. Setting `enable_offline_queue` to `false` will disable this feature and the callback will be executed immediately with an error, or an error will be emitted if no callback is specified. |
-| retry_max_delay | null | __Deprecated__ _Please use `retry_strategy` instead._ By default, every time the client tries to connect and fails, the reconnection delay almost doubles. This delay normally grows infinitely, but setting `retry_max_delay` limits it to the maximum value provided in milliseconds. |
-| connect_timeout | 3600000 | __Deprecated__ _Please use `retry_strategy` instead._ Setting `connect_timeout` limits the total time for the client to connect and reconnect. The value is provided in milliseconds and is counted from the moment a new client is created or from the time the connection is lost. The last retry is going to happen exactly at the timeout time. Default is to try connecting until the default system socket timeout has been exceeded and to try reconnecting until 1h has elapsed. |
-| max_attempts | 0 | __Deprecated__ _Please use `retry_strategy` instead._ By default, a client will try reconnecting until connected. Setting `max_attempts` limits total amount of connection attempts. Setting this to 1 will prevent any reconnect attempt. |
| retry_unfulfilled_commands | false | If set to `true`, all commands that were unfulfilled while the connection is lost will be retried after the connection has been reestablished. Use this with caution if you use state altering commands (e.g. `incr`). This is especially useful if you use blocking commands. |
| password | null | If set, client will run Redis auth command on connect. Alias `auth_pass` __Note__ `node_redis` < 2.5 must use `auth_pass` |
| db | null | If set, client will run Redis `select` command on connect. |
@@ -473,12 +461,6 @@ client.hgetall("hosts", function (err, obj) {
});
```
-Output:
-
-```js
-{ mjr: '1', another: '23', home: '1234' }
-```
-
### client.hmset(hash, obj[, callback])
Multiple values in a hash can be set by supplying an object:
@@ -770,7 +752,7 @@ clients.alterer = clients.watcher.duplicate();
clients.watcher.watch('foo',function(err) {
if (err) { throw err; }
//if you comment out the next line, the transaction will work
- clients.alterer.set('foo',Math.random(), (err) => {if (err) { throw err; }})
+ clients.alterer.set('foo',Math.random(), (err) => {if (err) { throw err; }});
//using a setTimeout here to ensure that the MULTI/EXEC will come after the SET.
//Normally, you would use a callback to ensure order, but I want the above SET command
@@ -897,8 +879,8 @@ the second word as first parameter:
```js
client.script('load', 'return 1');
-client.multi().script('load', 'return 1').exec(...);
-client.multi([['script', 'load', 'return 1']]).exec(...);
+client.multi().script('load', 'return 1').exec();
+client.multi([['script', 'load', 'return 1']]).exec();
```
## client.duplicate([options][, callback])
@@ -1082,6 +1064,7 @@ ReplyError: ERR wrong number of arguments for 'set' command
```
## How to Contribute
+
- Open a pull request or an issue about what you want to implement / change. We're glad for any help!
- Please be aware that we'll only accept fully tested code.
@@ -1097,23 +1080,3 @@ contributed to `node_redis` too. Thanks to all of them!
## License
[MIT](LICENSE)
-
-### Consolidation: It's time for celebration
-
-Right now there are two great redis clients around and both have some advantages
-above each other. We speak about ioredis and node_redis. So after talking to
-each other about how we could improve in working together we (that is @luin and
-@BridgeAR) decided to work towards a single library on the long run. But step by
-step.
-
-First of all, we want to split small parts of our libraries into others so that
-we're both able to use the same code. Those libraries are going to be maintained
-under the NodeRedis organization. This is going to reduce the maintenance
-overhead, allows others to use the very same code, if they need it and it's way
-easyer for others to contribute to both libraries.
-
-We're very happy about this step towards working together as we both want to
-give you the best redis experience possible.
-
-If you want to join our cause by help maintaining something, please don't
-hesitate to contact either one of us.
diff --git a/appveyor.yml b/appveyor.yml
index d9cd4f4b63..f8c16e9a4d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -3,7 +3,6 @@
# Test against these versions of Node.js.
environment:
matrix:
- - nodejs_version: "4"
- nodejs_version: "6"
- nodejs_version: "8"
- nodejs_version: "10"
diff --git a/index.js b/index.js
index b5acf785eb..bdbf46daf5 100644
--- a/index.js
+++ b/index.js
@@ -67,38 +67,16 @@ function RedisClient (options, stream) {
cnx_options.family = (!options.family && net.isIP(cnx_options.host)) || (options.family === 'IPv6' ? 6 : 4);
this.address = cnx_options.host + ':' + cnx_options.port;
}
- // Warn on misusing deprecated functions
- if (typeof options.retry_strategy === 'function') {
- if ('max_attempts' in options) {
- self.warn('WARNING: You activated the retry_strategy and max_attempts at the same time. This is not possible and max_attempts will be ignored.');
- // Do not print deprecation warnings twice
- delete options.max_attempts;
- }
- if ('retry_max_delay' in options) {
- self.warn('WARNING: You activated the retry_strategy and retry_max_delay at the same time. This is not possible and retry_max_delay will be ignored.');
- // Do not print deprecation warnings twice
- delete options.retry_max_delay;
- }
- }
this.connection_options = cnx_options;
this.connection_id = RedisClient.connection_id++;
this.connected = false;
this.ready = false;
- if (options.socket_nodelay === undefined) {
- options.socket_nodelay = true;
- } else if (!options.socket_nodelay) { // Only warn users with this set to false
- self.warn(
- 'socket_nodelay is deprecated and will be removed in v.3.0.0.\n' +
- 'Setting socket_nodelay to false likely results in a reduced throughput. Please use .batch for pipelining instead.\n' +
- 'If you are sure you rely on the NAGLE-algorithm you can activate it by calling client.stream.setNoDelay(false) instead.'
- );
- }
if (options.socket_keepalive === undefined) {
options.socket_keepalive = true;
}
- if (options.socket_initialdelay === undefined) {
- options.socket_initialdelay = 0;
+ if (options.socket_initial_delay === undefined) {
+ options.socket_initial_delay = 0;
// set default to 0, which is aligned to https://nodejs.org/api/net.html#net_socket_setkeepalive_enable_initialdelay
}
for (var command in options.rename_commands) {
@@ -116,14 +94,6 @@ function RedisClient (options, stream) {
this.handle_reply = handle_detect_buffers_reply;
}
this.should_buffer = false;
- this.max_attempts = options.max_attempts | 0;
- if ('max_attempts' in options) {
- self.warn(
- 'max_attempts is deprecated and will be removed in v.3.0.0.\n' +
- 'To reduce the number of options and to improve the reconnection handling please use the new `retry_strategy` option instead.\n' +
- 'This replaces the max_attempts and retry_max_delay option.'
- );
- }
this.command_queue = new Queue(); // Holds sent commands to de-pipeline them
this.offline_queue = new Queue(); // Holds commands issued but not able to be sent
this.pipeline_queue = new Queue(); // Holds all pipelined commands
@@ -131,14 +101,6 @@ function RedisClient (options, stream) {
// This should be done by the retry_strategy. Instead it should only be the timeout for connecting to redis
this.connect_timeout = +options.connect_timeout || 3600000; // 60 * 60 * 1000 ms
this.enable_offline_queue = options.enable_offline_queue === false ? false : true;
- this.retry_max_delay = +options.retry_max_delay || null;
- if ('retry_max_delay' in options) {
- self.warn(
- 'retry_max_delay is deprecated and will be removed in v.3.0.0.\n' +
- 'To reduce the amount of options and the improve the reconnection handling please use the new `retry_strategy` option instead.\n' +
- 'This replaces the max_attempts and retry_max_delay option.'
- );
- }
this.initialize_retry_vars();
this.pub_sub_mode = 0;
this.subscription_set = {};
@@ -158,17 +120,7 @@ function RedisClient (options, stream) {
this.create_stream();
// The listeners will not be attached right away, so let's print the deprecation message while the listener is attached
this.on('newListener', function (event) {
- if (event === 'idle') {
- this.warn(
- 'The idle event listener is deprecated and will likely be removed in v.3.0.0.\n' +
- 'If you rely on this feature please open a new ticket in node_redis with your use case'
- );
- } else if (event === 'drain') {
- this.warn(
- 'The drain event listener is deprecated and will be removed in v.3.0.0.\n' +
- 'If you want to keep on listening to this event please listen to the stream drain event directly.'
- );
- } else if ((event === 'message_buffer' || event === 'pmessage_buffer' || event === 'messageBuffer' || event === 'pmessageBuffer') && !this.buffers && !this.message_buffers) {
+ if ((event === 'message_buffer' || event === 'pmessage_buffer' || event === 'messageBuffer' || event === 'pmessageBuffer') && !this.buffers && !this.message_buffers) {
this.reply_parser.optionReturnBuffers = true;
this.message_buffers = true;
this.handle_reply = handle_detect_buffers_reply;
@@ -264,7 +216,6 @@ RedisClient.prototype.create_stream = function () {
// The buffer_from_socket.toString() has a significant impact on big chunks and therefore this should only be used if necessary
debug('Net read ' + self.address + ' id ' + self.connection_id); // + ': ' + buffer_from_socket.toString());
self.reply_parser.execute(buffer_from_socket);
- self.emit_idle();
});
this.stream.on('error', function (err) {
@@ -283,9 +234,7 @@ RedisClient.prototype.create_stream = function () {
self.drain();
});
- if (this.options.socket_nodelay) {
- this.stream.setNoDelay();
- }
+ this.stream.setNoDelay();
// Fire the command before redis is connected to be sure it's the first fired command
if (this.auth_pass !== undefined) {
@@ -387,7 +336,7 @@ RedisClient.prototype.on_error = function (err) {
this.connected = false;
this.ready = false;
- // Only emit the error if the retry_stategy option is not set
+ // Only emit the error if the retry_strategy option is not set
if (!this.options.retry_strategy) {
this.emit('error', err);
}
@@ -402,7 +351,7 @@ RedisClient.prototype.on_connect = function () {
this.connected = true;
this.ready = false;
this.emitted_end = false;
- this.stream.setKeepAlive(this.options.socket_keepalive, this.options.socket_initialdelay);
+ this.stream.setKeepAlive(this.options.socket_keepalive, this.options.socket_initial_delay);
this.stream.setTimeout(0);
this.emit('connect');
@@ -607,18 +556,31 @@ RedisClient.prototype.connection_gone = function (why, error) {
if (this.retry_delay instanceof Error) {
error = this.retry_delay;
}
+ var errorMessage = 'Redis connection in broken state: ';
+ if (this.retry_totaltime >= this.connect_timeout) {
+ errorMessage += 'connection timeout exceeded.';
+ } else {
+ errorMessage += 'maximum connection attempts exceeded.';
+ }
+
this.flush_and_error({
- message: 'Stream connection ended and command aborted.',
- code: 'NR_CLOSED'
+ message: errorMessage,
+ code: 'CONNECTION_BROKEN',
}, {
error: error
});
+ var retryError = new Error(errorMessage);
+ retryError.code = 'CONNECTION_BROKEN';
+ if (error) {
+ retryError.origin = error;
+ }
this.end(false);
+ this.emit('error', retryError);
return;
}
}
- if (this.max_attempts !== 0 && this.attempts >= this.max_attempts || this.retry_totaltime >= this.connect_timeout) {
+ if (this.retry_totaltime >= this.connect_timeout) {
var message = 'Redis connection in broken state: ';
if (this.retry_totaltime >= this.connect_timeout) {
message += 'connection timeout exceeded.';
@@ -637,8 +599,8 @@ RedisClient.prototype.connection_gone = function (why, error) {
if (error) {
err.origin = error;
}
- this.emit('error', err);
this.end(false);
+ this.emit('error', err);
return;
}
@@ -656,15 +618,12 @@ RedisClient.prototype.connection_gone = function (why, error) {
});
}
- if (this.retry_max_delay !== null && this.retry_delay > this.retry_max_delay) {
- this.retry_delay = this.retry_max_delay;
- } else if (this.retry_totaltime + this.retry_delay > this.connect_timeout) {
+ if (this.retry_totaltime + this.retry_delay > this.connect_timeout) {
// Do not exceed the maximum
this.retry_delay = this.connect_timeout - this.retry_totaltime;
}
debug('Retry connection in ' + this.retry_delay + ' ms');
-
this.retry_timer = setTimeout(retry_connection, this.retry_delay, this, error);
};
@@ -693,16 +652,9 @@ RedisClient.prototype.return_error = function (err) {
};
RedisClient.prototype.drain = function () {
- this.emit('drain');
this.should_buffer = false;
};
-RedisClient.prototype.emit_idle = function () {
- if (this.command_queue.length === 0 && this.pub_sub_mode === 0) {
- this.emit('idle');
- }
-};
-
function normal_reply (self, reply) {
var command_obj = self.command_queue.shift();
if (typeof command_obj.callback === 'function') {
@@ -752,7 +704,7 @@ function subscribe_unsubscribe (self, reply, type) {
self.command_queue.shift();
if (typeof command_obj.callback === 'function') {
// TODO: The current return value is pretty useless.
- // Evaluate to change this in v.3 to return all subscribed / unsubscribed channels in an array including the number of channels subscribed too
+ // Evaluate to change this in v.4 to return all subscribed / unsubscribed channels in an array including the number of channels subscribed too
command_obj.callback(null, channel);
}
self.sub_commands_left = 0;
@@ -768,7 +720,7 @@ function subscribe_unsubscribe (self, reply, type) {
function return_pub_sub (self, reply) {
var type = reply[0].toString();
if (type === 'message') { // channel, message
- if (!self.options.return_buffers || self.message_buffers) { // backwards compatible. Refactor this in v.3 to always return a string on the normal emitter
+ if (!self.options.return_buffers || self.message_buffers) { // backwards compatible. Refactor this in v.4 to always return a string on the normal emitter
self.emit('message', reply[1].toString(), reply[2].toString());
self.emit('message_buffer', reply[1], reply[2]);
self.emit('messageBuffer', reply[1], reply[2]);
@@ -776,7 +728,7 @@ function return_pub_sub (self, reply) {
self.emit('message', reply[1], reply[2]);
}
} else if (type === 'pmessage') { // pattern, channel, message
- if (!self.options.return_buffers || self.message_buffers) { // backwards compatible. Refactor this in v.3 to always return a string on the normal emitter
+ if (!self.options.return_buffers || self.message_buffers) { // backwards compatible. Refactor this in v.4 to always return a string on the normal emitter
self.emit('pmessage', reply[1].toString(), reply[2].toString(), reply[3].toString());
self.emit('pmessage_buffer', reply[1], reply[2], reply[3]);
self.emit('pmessageBuffer', reply[1], reply[2], reply[3]);
@@ -884,32 +836,39 @@ RedisClient.prototype.internal_send_command = function (command_obj) {
} else if (typeof args[i] === 'object') { // Checking for object instead of Buffer.isBuffer helps us finding data types that we can't handle properly
if (args[i] instanceof Date) { // Accept dates as valid input
args_copy[i] = args[i].toString();
- } else if (args[i] === null) {
- this.warn(
- 'Deprecated: The ' + command.toUpperCase() + ' command contains a "null" argument.\n' +
- 'This is converted to a "null" string now and will return an error from v.3.0 on.\n' +
- 'Please handle this in your code to make sure everything works as you intended it to.'
- );
- args_copy[i] = 'null'; // Backwards compatible :/
} else if (Buffer.isBuffer(args[i])) {
args_copy[i] = args[i];
command_obj.buffer_args = true;
big_data = true;
} else {
- this.warn(
- 'Deprecated: The ' + command.toUpperCase() + ' command contains a argument of type ' + args[i].constructor.name + '.\n' +
- 'This is converted to "' + args[i].toString() + '" by using .toString() now and will return an error from v.3.0 on.\n' +
- 'Please handle this in your code to make sure everything works as you intended it to.'
+ var invalidArgError = new Error(
+ 'node_redis: The ' + command.toUpperCase() + ' command contains a invalid argument type.\n' +
+ 'Only strings, dates and buffers are accepted. Please update your code to use valid argument types.'
);
- args_copy[i] = args[i].toString(); // Backwards compatible :/
+ invalidArgError.command = command_obj.command.toUpperCase();
+ if (command_obj.args && command_obj.args.length) {
+ invalidArgError.args = command_obj.args;
+ }
+ if (command_obj.callback) {
+ command_obj.callback(invalidArgError);
+ return false;
+ }
+ throw invalidArgError;
}
} else if (typeof args[i] === 'undefined') {
- this.warn(
- 'Deprecated: The ' + command.toUpperCase() + ' command contains a "undefined" argument.\n' +
- 'This is converted to a "undefined" string now and will return an error from v.3.0 on.\n' +
- 'Please handle this in your code to make sure everything works as you intended it to.'
+ var undefinedArgError = new Error(
+ 'node_redis: The ' + command.toUpperCase() + ' command contains a invalid argument type of "undefined".\n' +
+ 'Only strings, dates and buffers are accepted. Please update your code to use valid argument types.'
);
- args_copy[i] = 'undefined'; // Backwards compatible :/
+ undefinedArgError.command = command_obj.command.toUpperCase();
+ if (command_obj.args && command_obj.args.length) {
+ undefinedArgError.args = command_obj.args;
+ }
+ if (command_obj.callback) {
+ command_obj.callback(undefinedArgError);
+ return false;
+ }
+ throw undefinedArgError;
} else {
// Seems like numbers are converted fast using string concatenation
args_copy[i] = '' + args[i];
diff --git a/package.json b/package.json
index 015b93a8c7..e322fc6ef4 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "redis",
"version": "2.8.0",
- "description": "Redis client library",
+ "description": "A high performance Redis client.",
"keywords": [
"database",
"redis",
@@ -14,6 +14,16 @@
"backpressure"
],
"author": "Matt Ranney ",
+ "contributors": [
+ {
+ "name": "Mike Diarmid (Salakar)",
+ "url": "https://github.com/salakar"
+ },
+ {
+ "name": "Ruben Bridgewater (BridgeAR)",
+ "url": "https://github.com/BridgeAR"
+ }
+ ],
"license": "MIT",
"main": "./index.js",
"scripts": {
@@ -31,30 +41,34 @@
"redis-parser": "^3.0.0"
},
"engines": {
- "node": ">=4.0.0"
+ "node": ">=6"
},
"devDependencies": {
- "bluebird": "^3.0.2",
+ "bluebird": "^3.7.2",
"coveralls": "^2.11.2",
- "eslint": "^4.2.0",
+ "eslint": "^6.8.0",
"intercept-stdout": "~0.1.2",
- "metrics": "^0.1.9",
- "mocha": "^3.1.2",
- "nyc": "^10.0.0",
- "tcp-port-used": "^0.1.2",
- "uuid": "^2.0.1",
- "win-spawn": "^2.0.0"
+ "metrics": "^0.1.21",
+ "mocha": "^4.1.0",
+ "nyc": "^14.1.1",
+ "tcp-port-used": "^1.0.1",
+ "uuid": "^3.4.0",
+ "cross-spawn": "^6.0.5"
},
"repository": {
"type": "git",
- "url": "git://github.com/NodeRedis/node_redis.git"
+ "url": "git://github.com/NodeRedis/node-redis.git"
},
"bugs": {
- "url": "https://github.com/NodeRedis/node_redis/issues"
+ "url": "https://github.com/NodeRedis/node-redis/issues"
},
- "homepage": "https://github.com/NodeRedis/node_redis",
+ "homepage": "https://github.com/NodeRedis/node-redis",
"directories": {
"example": "examples",
"test": "test"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/node-redis"
}
}
diff --git a/test/auth.spec.js b/test/auth.spec.js
index 8411a4b618..67e6d0924a 100644
--- a/test/auth.spec.js
+++ b/test/auth.spec.js
@@ -192,7 +192,7 @@ describe('client authentication', function () {
client = redis.createClient.apply(null, args);
var async = true;
- client.auth(undefined, function (err, res) {
+ client.auth('undefined', function (err, res) {
assert.strictEqual(err.message, 'ERR invalid password');
assert.strictEqual(err.command, 'AUTH');
assert.strictEqual(res, undefined);
diff --git a/test/commands/hset.spec.js b/test/commands/hset.spec.js
index d0ce7f5481..c62b17713b 100644
--- a/test/commands/hset.spec.js
+++ b/test/commands/hset.spec.js
@@ -45,22 +45,16 @@ describe("The 'hset' method", function () {
});
});
- it('warns if someone passed a array either as field or as value', function (done) {
+ it('errors if someone passed a array either as field or as value', function (done) {
var hash = 'test hash';
var field = 'array';
- // This would be converted to "array contents" but if you use more than one entry,
- // it'll result in e.g. "array contents,second content" and this is not supported and considered harmful
var value = ['array contents'];
- client.on('warning', function (msg) {
- assert.strictEqual(
- msg,
- 'Deprecated: The HMSET command contains a argument of type Array.\n' +
- 'This is converted to "array contents" by using .toString() now and will return an error from v.3.0 on.\n' +
- 'Please handle this in your code to make sure everything works as you intended it to.'
- );
+ try {
+ client.HMSET(hash, field, value);
+ } catch (error) {
+ assert(/node_redis: The HMSET command contains a invalid argument type./.test(error.message));
done();
- });
- client.HMSET(hash, field, value);
+ }
});
it('does not error when a buffer and date are set as values on the same hash', function (done) {
diff --git a/test/commands/set.spec.js b/test/commands/set.spec.js
index 01b6244381..360cffe5f5 100644
--- a/test/commands/set.spec.js
+++ b/test/commands/set.spec.js
@@ -140,10 +140,14 @@ describe("The 'set' method", function () {
});
});
- // TODO: This test has to be refactored from v.3.0 on to expect an error instead
- it("converts null to 'null'", function (done) {
- client.set('foo', null);
- client.get('foo', helper.isString('null', done));
+ it('errors if null value is passed', function (done) {
+ try {
+ client.set('foo', null);
+ assert(false);
+ } catch (error) {
+ assert(/The SET command contains a invalid argument type./.test(error.message));
+ }
+ client.get('foo', helper.isNull(done));
});
it('emit an error with only the key set', function (done) {
diff --git a/test/connection.spec.js b/test/connection.spec.js
index f6dc8310cb..7ecee69853 100644
--- a/test/connection.spec.js
+++ b/test/connection.spec.js
@@ -152,40 +152,6 @@ describe('connection tests', function () {
describe('using ' + parser + ' and ' + ip, function () {
describe('on lost connection', function () {
- it('emit an error after max retry attempts and do not try to reconnect afterwards', function (done) {
- var maxAttempts = 3;
- var options = {
- parser: parser,
- maxAttempts: maxAttempts
- };
- client = redis.createClient(options);
- assert.strictEqual(client.retryBackoff, 1.7);
- assert.strictEqual(client.retryDelay, 200);
- assert.strictEqual(Object.keys(options).length, 2);
- var calls = 0;
-
- client.once('ready', function () {
- helper.killConnection(client);
- });
-
- client.on('reconnecting', function (params) {
- calls++;
- });
-
- client.on('error', function (err) {
- if (/Redis connection in broken state: maximum connection attempts.*?exceeded./.test(err.message)) {
- process.nextTick(function () { // End is called after the error got emitted
- assert.strictEqual(calls, maxAttempts - 1);
- assert.strictEqual(client.emitted_end, true);
- assert.strictEqual(client.connected, false);
- assert.strictEqual(client.ready, false);
- assert.strictEqual(client.closing, true);
- done();
- });
- }
- });
- });
-
it('emit an error after max retry timeout and do not try to reconnect afterwards', function (done) {
// TODO: Investigate why this test fails with windows. Reconnect is only triggered once
if (process.platform === 'win32') this.skip();
@@ -271,16 +237,11 @@ describe('connection tests', function () {
});
it('retryStrategy used to reconnect with individual error', function (done) {
- var text = '';
- var unhookIntercept = intercept(function (data) {
- text += data;
- return '';
- });
client = redis.createClient({
retryStrategy: function (options) {
if (options.totalRetryTime > 150) {
client.set('foo', 'bar', function (err, res) {
- assert.strictEqual(err.message, 'Stream connection ended and command aborted.');
+ assert.strictEqual(err.message, 'Redis connection in broken state: maximum connection attempts exceeded.');
assert.strictEqual(err.origin.message, 'Connection timeout');
done();
});
@@ -289,18 +250,8 @@ describe('connection tests', function () {
}
return Math.min(options.attempt * 25, 200);
},
- maxAttempts: 5,
- retryMaxDelay: 123,
port: 9999
});
- process.nextTick(function () {
- assert.strictEqual(
- text,
- 'node_redis: WARNING: You activated the retry_strategy and max_attempts at the same time. This is not possible and max_attempts will be ignored.\n' +
- 'node_redis: WARNING: You activated the retry_strategy and retry_max_delay at the same time. This is not possible and retry_max_delay will be ignored.\n'
- );
- unhookIntercept();
- });
});
it('retry_strategy used to reconnect', function (done) {
@@ -308,8 +259,8 @@ describe('connection tests', function () {
retry_strategy: function (options) {
if (options.total_retry_time > 150) {
client.set('foo', 'bar', function (err, res) {
- assert.strictEqual(err.message, 'Stream connection ended and command aborted.');
- assert.strictEqual(err.code, 'NR_CLOSED');
+ assert.strictEqual(err.message, 'Redis connection in broken state: maximum connection attempts exceeded.');
+ assert.strictEqual(err.code, 'CONNECTION_BROKEN');
assert.strictEqual(err.origin.code, 'ECONNREFUSED');
done();
});
@@ -337,11 +288,13 @@ describe('connection tests', function () {
client.stream.destroy();
}, 50);
client.on('error', function (err) {
- assert.strictEqual(err.code, 'NR_CLOSED');
- assert.strictEqual(err.message, 'Stream connection ended and command aborted.');
- unhookIntercept();
- redis.debugMode = false;
- done();
+ if (err instanceof redis.AbortError) {
+ assert.strictEqual(err.message, 'Redis connection in broken state: maximum connection attempts exceeded.');
+ assert.strictEqual(err.code, 'CONNECTION_BROKEN');
+ unhookIntercept();
+ redis.debugMode = false;
+ done();
+ }
});
});
});
diff --git a/test/lib/redis-process.js b/test/lib/redis-process.js
index c46fd8d70f..ce2f881edd 100644
--- a/test/lib/redis-process.js
+++ b/test/lib/redis-process.js
@@ -4,7 +4,7 @@
var config = require('./config');
var fs = require('fs');
var path = require('path');
-var spawn = require('win-spawn');
+var spawn = require('cross-spawn');
var tcpPortUsed = require('tcp-port-used');
var bluebird = require('bluebird');
diff --git a/test/multi.spec.js b/test/multi.spec.js
index 33ffdbe16c..233ead776c 100644
--- a/test/multi.spec.js
+++ b/test/multi.spec.js
@@ -219,17 +219,22 @@ describe("The 'multi' method", function () {
client = redis.createClient({
host: 'somewhere',
port: 6379,
- max_attempts: 1
+ retry_strategy: function (options) {
+ if (options.attempt > 1) {
+ // End reconnecting with built in error
+ return undefined;
+ }
+ }
});
client.on('error', function (err) {
- if (/Redis connection in broken state/.test(err.message)) {
+ if (/Redis connection to somewhere:6379 failed/.test(err.origin.message)) {
done();
}
});
client.multi([['set', 'foo', 'bar'], ['get', 'foo']]).exec(function (err, res) {
- assert(/Redis connection in broken state/.test(err.message));
+ assert(/Redis connection in broken state: maximum connection attempts exceeded/.test(err.message));
assert.strictEqual(err.errors.length, 2);
assert.strictEqual(err.errors[0].args.length, 2);
});
@@ -239,12 +244,17 @@ describe("The 'multi' method", function () {
client = redis.createClient({
host: 'somewhere',
port: 6379,
- max_attempts: 1
+ retry_strategy: function (options) {
+ if (options.attempt > 1) {
+ // End reconnecting with built in error
+ return undefined;
+ }
+ }
});
client.on('error', function (err) {
// Results in multiple done calls if test fails
- if (/Redis connection in broken state/.test(err.message)) {
+ if (/Redis connection to somewhere:6379 failed/.test(err.origin.message)) {
done();
}
});
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index d529d40da3..3c511ec9af 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -707,25 +707,6 @@ describe('The node_redis client', function () {
});
});
- describe('idle', function () {
- it('emits idle as soon as there are no outstanding commands', function (done) {
- var end = helper.callFuncAfter(done, 2);
- client.on('warning', function (msg) {
- assert.strictEqual(
- msg,
- 'The idle event listener is deprecated and will likely be removed in v.3.0.0.\n' +
- 'If you rely on this feature please open a new ticket in node_redis with your use case'
- );
- end();
- });
- client.on('idle', function onIdle () {
- client.removeListener('idle', onIdle);
- client.get('foo', helper.isString('bar', end));
- });
- client.set('foo', 'bar');
- });
- });
-
describe('utf8', function () {
it('handles utf-8 keys', function (done) {
var utf8_sample = 'ಠ_ಠ';
@@ -793,111 +774,6 @@ describe('The node_redis client', function () {
// });
});
- describe('socket_nodelay', function () {
- describe('true', function () {
- var args = config.configureClient(parser, ip, {
- socket_nodelay: true
- });
-
- it("fires client.on('ready')", function (done) {
- client = redis.createClient.apply(null, args);
- client.on('ready', function () {
- assert.strictEqual(true, client.options.socket_nodelay);
- client.quit(done);
- });
- });
-
- it('client is functional', function (done) {
- client = redis.createClient.apply(null, args);
- client.on('ready', function () {
- assert.strictEqual(true, client.options.socket_nodelay);
- client.set(['set key 1', 'set val'], helper.isString('OK'));
- client.set(['set key 2', 'set val'], helper.isString('OK'));
- client.get(['set key 1'], helper.isString('set val'));
- client.get(['set key 2'], helper.isString('set val'));
- client.quit(done);
- });
- });
- });
-
- describe('false', function () {
- var args = config.configureClient(parser, ip, {
- socket_nodelay: false
- });
-
- it("fires client.on('ready')", function (done) {
- client = redis.createClient.apply(null, args);
- client.on('ready', function () {
- assert.strictEqual(false, client.options.socket_nodelay);
- client.quit(done);
- });
- });
-
- it('client is functional', function (done) {
- client = redis.createClient.apply(null, args);
- client.on('ready', function () {
- assert.strictEqual(false, client.options.socket_nodelay);
- client.set(['set key 1', 'set val'], helper.isString('OK'));
- client.set(['set key 2', 'set val'], helper.isString('OK'));
- client.get(['set key 1'], helper.isString('set val'));
- client.get(['set key 2'], helper.isString('set val'));
- client.quit(done);
- });
- });
- });
-
- describe('defaults to true', function () {
-
- it("fires client.on('ready')", function (done) {
- client = redis.createClient.apply(null, args);
- client.on('ready', function () {
- assert.strictEqual(true, client.options.socket_nodelay);
- client.quit(done);
- });
- });
-
- it('client is functional', function (done) {
- client = redis.createClient.apply(null, args);
- client.on('ready', function () {
- assert.strictEqual(true, client.options.socket_nodelay);
- client.set(['set key 1', 'set val'], helper.isString('OK'));
- client.set(['set key 2', 'set val'], helper.isString('OK'));
- client.get(['set key 1'], helper.isString('set val'));
- client.get(['set key 2'], helper.isString('set val'));
- client.quit(done);
- });
- });
- });
- });
-
- describe('retry_max_delay', function () {
- it('sets upper bound on how long client waits before reconnecting', function (done) {
- var time;
- var timeout = process.platform !== 'win32' ? 20 : 100;
-
- client = redis.createClient.apply(null, config.configureClient(parser, ip, {
- retry_max_delay: 1 // ms
- }));
- client.on('ready', function () {
- if (this.times_connected === 1) {
- this.stream.end();
- time = Date.now();
- } else {
- done();
- }
- });
- client.on('reconnecting', function () {
- time = Date.now() - time;
- assert(time < timeout, 'The reconnect should not have taken longer than ' + timeout + ' but it took ' + time);
- });
- client.on('error', function (err) {
- // This is rare but it might be triggered.
- // So let's have a robust test
- assert.strictEqual(err.code, 'ECONNRESET');
- });
- });
- });
-
describe('protocol error', function () {
it('should gracefully recover and only fail on the already send commands', function (done) {
@@ -932,33 +808,9 @@ describe('The node_redis client', function () {
describe('enable_offline_queue', function () {
describe('true', function () {
- it('should emit drain if offline queue is flushed and nothing to buffer', function (done) {
- client = redis.createClient({
- parser: parser,
- no_ready_check: true
- });
- var end = helper.callFuncAfter(done, 3);
- client.set('foo', 'bar');
- client.get('foo', end);
- client.on('warning', function (msg) {
- assert.strictEqual(
- msg,
- 'The drain event listener is deprecated and will be removed in v.3.0.0.\n' +
- 'If you want to keep on listening to this event please listen to the stream drain event directly.'
- );
- end();
- });
- client.on('drain', function () {
- assert(client.offline_queue.length === 0);
- end();
- });
- });
it('does not return an error and enqueues operation', function (done) {
- client = redis.createClient(9999, null, {
- max_attempts: 0,
- parser: parser
- });
+ client = redis.createClient(9999, null);
var finished = false;
client.on('error', function (e) {
// ignore, b/c expecting a "can't connect" error
@@ -980,8 +832,12 @@ describe('The node_redis client', function () {
it('enqueues operation and keep the queue while trying to reconnect', function (done) {
client = redis.createClient(9999, null, {
- max_attempts: 4,
- parser: parser
+ retry_strategy: function (options) {
+ if (options.attempt > 4) {
+ return undefined;
+ }
+ return 100;
+ },
});
var i = 0;
From 144b7edd8562b2c3cb5046fc8c0797201ccadaaf Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 02:08:46 +0000
Subject: [PATCH 60/96] start of work towards v3 release
---
README.md | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index e4f60d3ab3..77197ed717 100644
--- a/README.md
+++ b/README.md
@@ -1,34 +1,38 @@
-
+
Node Redis
- A high performance Node.js Redis client.
+ A high performance Node.js Redis client.
+---
+
-
+
---
-This is a complete and feature rich Redis client for node.js. __It supports all
+This is a complete and feature rich Redis client for Node.js. __It supports all
Redis commands__ and focuses on high performance.
Install with:
- npm install redis
+```bash
+npm install redis
+```
## Usage Example
```js
-var redis = require("redis"),
- client = redis.createClient();
+const redis = require("redis");
+const client = redis.createClient();
// if you'd like to select database 3, instead of 0 (default), call
// client.select(3, function() { /* ... */ });
@@ -69,6 +73,7 @@ landscape.
### Promises
#### Native Promises
+
If you are using node v8 or higher, you can promisify node_redis with [util.promisify](https://nodejs.org/api/util.html#util_util_promisify_original) as in:
```js
const {promisify} = require('util');
@@ -92,6 +97,7 @@ async function myFunc() {
```
#### Bluebird Promises
+
You can also use node_redis with promises by promisifying node_redis with
[bluebird](https://github.com/petkaantonov/bluebird) as in:
From bb05064b143584f8e01bd4da3b52b93ee90ea64e Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 02:15:44 +0000
Subject: [PATCH 61/96] format docs
---
.prettierrc | 11 +
CODE_OF_CONDUCT.md | 20 +-
README.md | 526 ++++++++++++++++++++++++---------------------
package.json | 1 +
4 files changed, 302 insertions(+), 256 deletions(-)
create mode 100644 .prettierrc
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000000..951c38fd13
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,11 @@
+{
+ "arrowParens": "avoid",
+ "trailingComma": "all",
+ "useTabs": false,
+ "semi": true,
+ "singleQuote": true,
+ "bracketSpacing": true,
+ "jsxBracketSameLine": false,
+ "tabWidth": 2,
+ "printWidth": 100
+}
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 00aad77d08..50b0a74108 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -8,19 +8,19 @@ In the interest of fostering an open and welcoming environment, we as contributo
Examples of behavior that contributes to creating a positive environment include:
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
+- Using welcoming and inclusive language
+- Being respectful of differing viewpoints and experiences
+- Gracefully accepting constructive criticism
+- Focusing on what is best for the community
+- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
-* The use of sexualized language or imagery and unwelcome sexual attention or advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a professional setting
+- The use of sexualized language or imagery and unwelcome sexual attention or advances
+- Trolling, insulting/derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or electronic address, without explicit permission
+- Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
diff --git a/README.md b/README.md
index 77197ed717..bd124739b2 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
+
Node Redis
A high performance Node.js Redis client.
@@ -12,15 +12,15 @@
-
+
---
-This is a complete and feature rich Redis client for Node.js. __It supports all
-Redis commands__ and focuses on high performance.
+This is a complete and feature rich Redis client for Node.js. **It supports all
+Redis commands** and focuses on high performance.
Install with:
@@ -31,25 +31,25 @@ npm install redis
## Usage Example
```js
-const redis = require("redis");
+const redis = require('redis');
const client = redis.createClient();
// if you'd like to select database 3, instead of 0 (default), call
// client.select(3, function() { /* ... */ });
-client.on("error", function (err) {
- console.log("Error " + err);
+client.on('error', function(err) {
+ console.log('Error ' + err);
});
-client.set("string key", "string val", redis.print);
-client.hset("hash key", "hashtest 1", "some value", redis.print);
-client.hset(["hash key", "hashtest 2", "some other value"], redis.print);
-client.hkeys("hash key", function (err, replies) {
- console.log(replies.length + " replies:");
- replies.forEach(function (reply, i) {
- console.log(" " + i + ": " + reply);
- });
- client.quit();
+client.set('string key', 'string val', redis.print);
+client.hset('hash key', 'hashtest 1', 'some value', redis.print);
+client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
+client.hkeys('hash key', function(err, replies) {
+ console.log(replies.length + ' replies:');
+ replies.forEach(function(reply, i) {
+ console.log(' ' + i + ': ' + reply);
+ });
+ client.quit();
});
```
@@ -75,24 +75,28 @@ landscape.
#### Native Promises
If you are using node v8 or higher, you can promisify node_redis with [util.promisify](https://nodejs.org/api/util.html#util_util_promisify_original) as in:
+
```js
-const {promisify} = require('util');
+const { promisify } = require('util');
const getAsync = promisify(client.get).bind(client);
```
-now *getAsync* is a promisified version of *client.get*:
+
+now _getAsync_ is a promisified version of _client.get_:
+
```js
// We expect a value 'foo': 'bar' to be present
// So instead of writing client.get('foo', cb); you have to write:
return getAsync('foo').then(function(res) {
- console.log(res); // => 'bar'
+ console.log(res); // => 'bar'
});
```
or using [async await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function):
+
```js
async function myFunc() {
- const res = await getAsync('foo');
- console.log(res);
+ const res = await getAsync('foo');
+ console.log(res);
}
```
@@ -106,20 +110,24 @@ const redis = require('redis');
bluebird.promisifyAll(redis);
```
-It'll add a *Async* to all node_redis functions (e.g. return client.getAsync().then())
+It'll add a _Async_ to all node_redis functions (e.g. return client.getAsync().then())
```js
// We expect a value 'foo': 'bar' to be present
// So instead of writing client.get('foo', cb); you have to write:
return client.getAsync('foo').then(function(res) {
- console.log(res); // => 'bar'
+ console.log(res); // => 'bar'
});
// Using multi with promises looks like:
-return client.multi().get('foo').execAsync().then(function(res) {
+return client
+ .multi()
+ .get('foo')
+ .execAsync()
+ .then(function(res) {
console.log(res); // => 'bar'
-});
+ });
```
### Sending Commands
@@ -130,11 +138,18 @@ a variable number of individual arguments followed by an optional callback.
Examples:
```js
-client.hmset(["key", "test keys 1", "test val 1", "test keys 2", "test val 2"], function (err, res) {});
+client.hmset(['key', 'test keys 1', 'test val 1', 'test keys 2', 'test val 2'], function(
+ err,
+ res,
+) {});
// Works the same as
-client.hmset("key", ["test keys 1", "test val 1", "test keys 2", "test val 2"], function (err, res) {});
+client.hmset('key', ['test keys 1', 'test val 1', 'test keys 2', 'test val 2'], function(err, res) {
+ // ...
+});
// Or
-client.hmset("key", "test keys 1", "test val 1", "test keys 2", "test val 2", function (err, res) {});
+client.hmset('key', 'test keys 1', 'test val 1', 'test keys 2', 'test val 2', function(err, res) {
+ // ...
+});
```
Care should be taken with user input if arrays are possible (via body-parser, query string or other method), as single arguments could be unintentionally interpreted as multiple args.
@@ -142,17 +157,17 @@ Care should be taken with user input if arrays are possible (via body-parser, qu
Note that in either form the `callback` is optional:
```js
-client.set("some key", "some val");
-client.set(["some other key", "some val"]);
+client.set('some key', 'some val');
+client.set(['some other key', 'some val']);
```
If the key is missing, reply will be null. Only if the [Redis Command
Reference](http://redis.io/commands) states something else it will not be null.
```js
-client.get("missingkey", function(err, reply) {
- // reply is null when the key is missing
- console.log(reply);
+client.get('missingkey', function(err, reply) {
+ // reply is null when the key is missing
+ console.log(reply);
});
```
@@ -218,85 +233,87 @@ So please attach the error listener to node_redis.
deprecated option / function / similar is used.
## redis.createClient()
+
If you have `redis-server` running on the same machine as node, then the
defaults for port and host are probably fine and you don't need to supply any
arguments. `createClient()` returns a `RedisClient` object. Otherwise,
`createClient()` accepts these arguments:
-* `redis.createClient([options])`
-* `redis.createClient(unix_socket[, options])`
-* `redis.createClient(redis_url[, options])`
-* `redis.createClient(port[, host][, options])`
+- `redis.createClient([options])`
+- `redis.createClient(unix_socket[, options])`
+- `redis.createClient(redis_url[, options])`
+- `redis.createClient(port[, host][, options])`
-__Tip:__ If the Redis server runs on the same machine as the client consider
+**Tip:** If the Redis server runs on the same machine as the client consider
using unix sockets if possible to increase throughput.
-__Note:__ Using `'rediss://...` for the protocol in a `redis_url` will enable a TLS socket connection. However, additional TLS options will need to be passed in `options`, if required.
+**Note:** Using `'rediss://...` for the protocol in a `redis_url` will enable a TLS socket connection. However, additional TLS options will need to be passed in `options`, if required.
#### `options` object properties
-| Property | Default | Description |
-|-----------|-----------|-------------|
-| host | 127.0.0.1 | IP address of the Redis server |
-| port | 6379 | Port of the Redis server |
-| path | null | The UNIX socket string of the Redis server |
-| url | null | The URL of the Redis server. Format: `[redis[s]:]//[[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)). |
-| 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. |
-| return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. |
-| 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. |
-| socket_keepalive | true | If set to `true`, the keep-alive functionality is enabled on the underlying socket. |
-| socket_initial_delay | 0 | Initial Delay in milliseconds, and this will also behave the interval keep alive message sending to Redis. |
-| no_ready_check | false | When a connection is established to the Redis server, the server might still be loading the database from disk. While loading, the server will not respond to any commands. To work around this, `node_redis` has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command indicates whether the server is ready for more commands. When ready, `node_redis` emits a `ready` event. Setting `no_ready_check` to `true` will inhibit this check. |
-| enable_offline_queue | true | By default, if there is no active connection to the Redis server, commands are added to a queue and are executed once the connection has been established. Setting `enable_offline_queue` to `false` will disable this feature and the callback will be executed immediately with an error, or an error will be emitted if no callback is specified. |
-| retry_unfulfilled_commands | false | If set to `true`, all commands that were unfulfilled while the connection is lost will be retried after the connection has been reestablished. Use this with caution if you use state altering commands (e.g. `incr`). This is especially useful if you use blocking commands. |
-| password | null | If set, client will run Redis auth command on connect. Alias `auth_pass` __Note__ `node_redis` < 2.5 must use `auth_pass` |
-| db | null | If set, client will run Redis `select` command on connect. |
-| family | IPv4 | You can force using IPv6 if you set the family to 'IPv6'. See Node.js [net](https://nodejs.org/api/net.html) or [dns](https://nodejs.org/api/dns.html) modules on how to use the family type. |
-| disable_resubscribing | false | If set to `true`, a client won't resubscribe after disconnecting. |
-| rename_commands | null | Passing an object with renamed commands to use instead of the original functions. For example, if you renamed the command KEYS to "DO-NOT-USE" then the rename_commands object would be: `{ KEYS : "DO-NOT-USE" }` . See the [Redis security topics](http://redis.io/topics/security) for more info. |
-| tls | null | An object containing options to pass to [tls.connect](http://nodejs.org/api/tls.html#tls_tls_connect_port_host_options_callback) to set up a TLS connection to Redis (if, for example, it is set up to be accessible via a tunnel). |
-| prefix | null | A string used to prefix all used keys (e.g. `namespace:test`). Please be aware that the `keys` command will not be prefixed. The `keys` command has a "pattern" as argument and no key and it would be impossible to determine the existing keys in Redis if this would be prefixed. |
-| retry_strategy | function | A function that receives an options object as parameter including the retry `attempt`, the `total_retry_time` indicating how much time passed since the last time connected, the `error` why the connection was lost and the number of `times_connected` in total. If you return a number from this function, the retry will happen exactly after that time in milliseconds. If you return a non-number, no further retry will happen and all offline commands are flushed with errors. Return an error to return that specific error to all offline commands. Example below. |
+
+| Property | Default | Description |
+| -------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| host | 127.0.0.1 | IP address of the Redis server |
+| port | 6379 | Port of the Redis server |
+| path | null | The UNIX socket string of the Redis server |
+| url | null | The URL of the Redis server. Format: `[redis[s]:]//[[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)). |
+| 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. |
+| return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. |
+| 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. |
+| socket_keepalive | true | If set to `true`, the keep-alive functionality is enabled on the underlying socket. |
+| socket_initial_delay | 0 | Initial Delay in milliseconds, and this will also behave the interval keep alive message sending to Redis. |
+| no_ready_check | false | When a connection is established to the Redis server, the server might still be loading the database from disk. While loading, the server will not respond to any commands. To work around this, `node_redis` has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command indicates whether the server is ready for more commands. When ready, `node_redis` emits a `ready` event. Setting `no_ready_check` to `true` will inhibit this check. |
+| enable_offline_queue | true | By default, if there is no active connection to the Redis server, commands are added to a queue and are executed once the connection has been established. Setting `enable_offline_queue` to `false` will disable this feature and the callback will be executed immediately with an error, or an error will be emitted if no callback is specified. |
+| retry_unfulfilled_commands | false | If set to `true`, all commands that were unfulfilled while the connection is lost will be retried after the connection has been reestablished. Use this with caution if you use state altering commands (e.g. `incr`). This is especially useful if you use blocking commands. |
+| password | null | If set, client will run Redis auth command on connect. Alias `auth_pass` **Note** `node_redis` < 2.5 must use `auth_pass` |
+| db | null | If set, client will run Redis `select` command on connect. |
+| family | IPv4 | You can force using IPv6 if you set the family to 'IPv6'. See Node.js [net](https://nodejs.org/api/net.html) or [dns](https://nodejs.org/api/dns.html) modules on how to use the family type. |
+| disable_resubscribing | false | If set to `true`, a client won't resubscribe after disconnecting. |
+| rename_commands | null | Passing an object with renamed commands to use instead of the original functions. For example, if you renamed the command KEYS to "DO-NOT-USE" then the rename_commands object would be: `{ KEYS : "DO-NOT-USE" }` . See the [Redis security topics](http://redis.io/topics/security) for more info. |
+| tls | null | An object containing options to pass to [tls.connect](http://nodejs.org/api/tls.html#tls_tls_connect_port_host_options_callback) to set up a TLS connection to Redis (if, for example, it is set up to be accessible via a tunnel). |
+| prefix | null | A string used to prefix all used keys (e.g. `namespace:test`). Please be aware that the `keys` command will not be prefixed. The `keys` command has a "pattern" as argument and no key and it would be impossible to determine the existing keys in Redis if this would be prefixed. |
+| retry_strategy | function | A function that receives an options object as parameter including the retry `attempt`, the `total_retry_time` indicating how much time passed since the last time connected, the `error` why the connection was lost and the number of `times_connected` in total. If you return a number from this function, the retry will happen exactly after that time in milliseconds. If you return a non-number, no further retry will happen and all offline commands are flushed with errors. Return an error to return that specific error to all offline commands. Example below. |
```js
-var redis = require("redis");
-var client = redis.createClient({detect_buffers: true});
+var redis = require('redis');
+var client = redis.createClient({ detect_buffers: true });
-client.set("foo_rand000000000000", "OK");
+client.set('foo_rand000000000000', 'OK');
// This will return a JavaScript String
-client.get("foo_rand000000000000", function (err, reply) {
- console.log(reply.toString()); // Will print `OK`
+client.get('foo_rand000000000000', function(err, reply) {
+ console.log(reply.toString()); // Will print `OK`
});
// This will return a Buffer since original key is specified as a Buffer
-client.get(new Buffer("foo_rand000000000000"), function (err, reply) {
- console.log(reply.toString()); // Will print ``
+client.get(new Buffer('foo_rand000000000000'), function(err, reply) {
+ console.log(reply.toString()); // Will print ``
});
client.quit();
```
-retry_strategy example
+#### `retry_strategy` example
```js
var client = redis.createClient({
- retry_strategy: function (options) {
- if (options.error && options.error.code === 'ECONNREFUSED') {
- // End reconnecting on a specific error and flush all commands with
- // a individual error
- return new Error('The server refused the connection');
- }
- if (options.total_retry_time > 1000 * 60 * 60) {
- // End reconnecting after a specific timeout and flush all commands
- // with a individual error
- return new Error('Retry time exhausted');
- }
- if (options.attempt > 10) {
- // End reconnecting with built in error
- return undefined;
- }
- // reconnect after
- return Math.min(options.attempt * 100, 3000);
+ retry_strategy: function(options) {
+ if (options.error && options.error.code === 'ECONNREFUSED') {
+ // End reconnecting on a specific error and flush all commands with
+ // a individual error
+ return new Error('The server refused the connection');
}
+ if (options.total_retry_time > 1000 * 60 * 60) {
+ // End reconnecting after a specific timeout and flush all commands
+ // with a individual error
+ return new Error('Retry time exhausted');
+ }
+ if (options.attempt > 10) {
+ // End reconnecting with built in error
+ return undefined;
+ }
+ // reconnect after
+ return Math.min(options.attempt * 100, 3000);
+ },
});
```
@@ -346,17 +363,17 @@ This example closes the connection to the Redis server before the replies have
been read. You probably don't want to do this:
```js
-var redis = require("redis"),
- client = redis.createClient();
+var redis = require('redis'),
+ client = redis.createClient();
-client.set("foo_rand000000000000", "some fantastic value", function (err, reply) {
- // This will either result in an error (flush parameter is set to true)
- // or will silently fail and this callback will not be called at all (flush set to false)
- console.log(err);
+client.set('foo_rand000000000000', 'some fantastic value', function(err, reply) {
+ // This will either result in an error (flush parameter is set to true)
+ // or will silently fail and this callback will not be called at all (flush set to false)
+ console.log(err);
});
client.end(true); // No further commands will be processed
-client.get("foo_rand000000000000", function (err, reply) {
- console.log(err); // => 'The connection has already been closed.'
+client.get('foo_rand000000000000', function(err, reply) {
+ console.log(err); // => 'The connection has already been closed.'
});
```
@@ -366,47 +383,48 @@ client.get("foo_rand000000000000", function (err, reply) {
Currently the following error subclasses exist:
-* `RedisError`: _All errors_ returned by the client
-* `ReplyError` subclass of `RedisError`: All errors returned by __Redis__ itself
-* `AbortError` subclass of `RedisError`: All commands that could not finish due
+- `RedisError`: _All errors_ returned by the client
+- `ReplyError` subclass of `RedisError`: All errors returned by **Redis** itself
+- `AbortError` subclass of `RedisError`: All commands that could not finish due
to what ever reason
-* `ParserError` subclass of `RedisError`: Returned in case of a parser error
+- `ParserError` subclass of `RedisError`: Returned in case of a parser error
(this should not happen)
-* `AggregateError` subclass of `AbortError`: Emitted in case multiple unresolved
+- `AggregateError` subclass of `AbortError`: Emitted in case multiple unresolved
commands without callback got rejected in debug_mode instead of lots of
`AbortError`s.
All error classes are exported by the module.
Example:
+
```js
var redis = require('./');
var assert = require('assert');
var client = redis.createClient();
-client.on('error', function (err) {
- assert(err instanceof Error);
- assert(err instanceof redis.AbortError);
- assert(err instanceof redis.AggregateError);
- // The set and get get aggregated in here
- assert.strictEqual(err.errors.length, 2);
- assert.strictEqual(err.code, 'NR_CLOSED');
+client.on('error', function(err) {
+ assert(err instanceof Error);
+ assert(err instanceof redis.AbortError);
+ assert(err instanceof redis.AggregateError);
+ // The set and get get aggregated in here
+ assert.strictEqual(err.errors.length, 2);
+ assert.strictEqual(err.code, 'NR_CLOSED');
});
-client.set('foo', 123, 'bar', function (err, res) { // Too many arguments
- assert(err instanceof redis.ReplyError); // => true
- assert.strictEqual(err.command, 'SET');
- assert.deepStrictEqual(err.args, ['foo', 123, 'bar']);
+client.set('foo', 123, 'bar', function(err, res) {
+ // Too many arguments
+ assert(err instanceof redis.ReplyError); // => true
+ assert.strictEqual(err.command, 'SET');
+ assert.deepStrictEqual(err.args, ['foo', 123, 'bar']);
- redis.debug_mode = true;
- client.set('foo', 'bar');
- client.get('foo');
- process.nextTick(function () {
- // Force closing the connection while the command did not yet return
- client.end(true);
- redis.debug_mode = false;
- });
+ redis.debug_mode = true;
+ client.set('foo', 'bar');
+ client.get('foo');
+ process.nextTick(function() {
+ // Force closing the connection while the command did not yet return
+ client.end(true);
+ redis.debug_mode = false;
+ });
});
-
```
Every `ReplyError` contains the `command` name in all-caps and the arguments (`args`).
@@ -414,7 +432,7 @@ Every `ReplyError` contains the `command` name in all-caps and the arguments (`a
If node_redis emits a library error because of another error, the triggering
error is added to the returned error as `origin` attribute.
-___Error codes___
+**_Error codes_**
node_redis returns a `NR_CLOSED` error code if the clients connection dropped.
If a command unresolved command got rejected a `UNCERTAIN_STATE` code is
@@ -428,10 +446,10 @@ the program to exit once no more commands are pending.
This is an **experimental** feature, and only supports a subset of the Redis
protocol. Any commands where client state is saved on the Redis server, e.g.
-`*SUBSCRIBE` or the blocking `BL*` commands will *NOT* work with `.unref()`.
+`*SUBSCRIBE` or the blocking `BL*` commands will _NOT_ work with `.unref()`.
```js
-var redis = require("redis");
+var redis = require('redis');
var client = redis.createClient();
/*
@@ -440,9 +458,9 @@ var client = redis.createClient();
client-server connection is alive.
*/
client.unref();
-client.get("foo", function (err, value) {
- if (err) throw(err);
- console.log(value);
+client.get('foo', function(err, value) {
+ if (err) throw err;
+ console.log(value);
});
```
@@ -461,9 +479,9 @@ syntax.
Example:
```js
-client.hmset("hosts", "mjr", "1", "another", "23", "home", "1234");
-client.hgetall("hosts", function (err, obj) {
- console.dir(obj);
+client.hmset('hosts', 'mjr', '1', 'another', '23', 'home', '1234');
+client.hgetall('hosts', function(err, obj) {
+ console.dir(obj);
});
```
@@ -473,8 +491,8 @@ Multiple values in a hash can be set by supplying an object:
```js
client.HMSET(key2, {
- "0123456789": "abcdefghij", // NOTE: key and value will be coerced to strings
- "some manner of key": "a type of value"
+ '0123456789': 'abcdefghij', // NOTE: key and value will be coerced to strings
+ 'some manner of key': 'a type of value',
});
```
@@ -486,7 +504,7 @@ Redis hash.
Multiple values may also be set by supplying a list:
```js
-client.HMSET(key1, "0123456789", "abcdefghij", "some manner of key", "a type of value");
+client.HMSET(key1, '0123456789', 'abcdefghij', 'some manner of key', 'a type of value');
```
## Publish / Subscribe
@@ -496,27 +514,28 @@ client connections, subscribes to a channel on one of them, and publishes to tha
channel on the other:
```js
-var redis = require("redis");
-var sub = redis.createClient(), pub = redis.createClient();
+var redis = require('redis');
+var sub = redis.createClient(),
+ pub = redis.createClient();
var msg_count = 0;
-sub.on("subscribe", function (channel, count) {
- pub.publish("a nice channel", "I am sending a message.");
- pub.publish("a nice channel", "I am sending a second message.");
- pub.publish("a nice channel", "I am sending my last message.");
+sub.on('subscribe', function(channel, count) {
+ pub.publish('a nice channel', 'I am sending a message.');
+ pub.publish('a nice channel', 'I am sending a second message.');
+ pub.publish('a nice channel', 'I am sending my last message.');
});
-sub.on("message", function (channel, message) {
- console.log("sub channel " + channel + ": " + message);
- msg_count += 1;
- if (msg_count === 3) {
- sub.unsubscribe();
- sub.quit();
- pub.quit();
- }
+sub.on('message', function(channel, message) {
+ console.log('sub channel ' + channel + ': ' + message);
+ msg_count += 1;
+ if (msg_count === 3) {
+ sub.unsubscribe();
+ sub.quit();
+ pub.quit();
+ }
});
-sub.subscribe("a nice channel");
+sub.subscribe('a nice channel');
```
When a client issues a `SUBSCRIBE` or `PSUBSCRIBE`, that connection is put into
@@ -591,33 +610,35 @@ further information look at
[transactions](http://redis.io/topics/transactions)).
```js
-var redis = require("./index"),
- client = redis.createClient(), set_size = 20;
+var redis = require('./index'),
+ client = redis.createClient(),
+ set_size = 20;
-client.sadd("bigset", "a member");
-client.sadd("bigset", "another member");
+client.sadd('bigset', 'a member');
+client.sadd('bigset', 'another member');
while (set_size > 0) {
- client.sadd("bigset", "member " + set_size);
- set_size -= 1;
+ client.sadd('bigset', 'member ' + set_size);
+ set_size -= 1;
}
// multi chain with an individual callback
-client.multi()
- .scard("bigset")
- .smembers("bigset")
- .keys("*", function (err, replies) {
- // NOTE: code in this callback is NOT atomic
- // this only happens after the the .exec call finishes.
- client.mget(replies, redis.print);
- })
- .dbsize()
- .exec(function (err, replies) {
- console.log("MULTI got " + replies.length + " replies");
- replies.forEach(function (reply, index) {
- console.log("Reply " + index + ": " + reply.toString());
- });
+client
+ .multi()
+ .scard('bigset')
+ .smembers('bigset')
+ .keys('*', function(err, replies) {
+ // NOTE: code in this callback is NOT atomic
+ // this only happens after the the .exec call finishes.
+ client.mget(replies, redis.print);
+ })
+ .dbsize()
+ .exec(function(err, replies) {
+ console.log('MULTI got ' + replies.length + ' replies');
+ replies.forEach(function(reply, index) {
+ console.log('Reply ' + index + ': ' + reply.toString());
});
+ });
```
### Multi.exec([callback])
@@ -638,20 +659,21 @@ can queue individual commands while still sending regular client command as in
this example:
```js
-var redis = require("redis"),
- client = redis.createClient(), multi;
+var redis = require('redis'),
+ client = redis.createClient(),
+ multi;
// start a separate multi command queue
multi = client.multi();
-multi.incr("incr thing", redis.print);
-multi.incr("incr other thing", redis.print);
+multi.incr('incr thing', redis.print);
+multi.incr('incr other thing', redis.print);
// runs immediately
-client.mset("incr thing", 100, "incr other thing", 1, redis.print);
+client.mset('incr thing', 100, 'incr other thing', 1, redis.print);
// drains multi queue and runs atomically
-multi.exec(function (err, replies) {
- console.log(replies); // 101, 2
+multi.exec(function(err, replies) {
+ console.log(replies); // 101, 2
});
```
@@ -659,16 +681,18 @@ In addition to adding commands to the `MULTI` queue individually, you can also
pass an array of commands and arguments to the constructor:
```js
-var redis = require("redis"),
- client = redis.createClient();
+var redis = require('redis'),
+ client = redis.createClient();
-client.multi([
- ["mget", "multifoo", "multibar", redis.print],
- ["incr", "multifoo"],
- ["incr", "multibar"]
-]).exec(function (err, replies) {
+client
+ .multi([
+ ['mget', 'multifoo', 'multibar', redis.print],
+ ['incr', 'multifoo'],
+ ['incr', 'multibar'],
+ ])
+ .exec(function(err, replies) {
console.log(replies);
-});
+ });
```
### Multi.exec_atomic([callback])
@@ -695,11 +719,11 @@ commands are kept in memory until they are fired.
## Optimistic Locks
-Using `multi` you can make sure your modifications run as a transaction, but you
-can't be sure you got there first. What if another client modified a key while
+Using `multi` you can make sure your modifications run as a transaction, but you
+can't be sure you got there first. What if another client modified a key while
you were working with it's data?
-To solve this, Redis supports the [WATCH](https://redis.io/topics/transactions)
+To solve this, Redis supports the [WATCH](https://redis.io/topics/transactions)
command, which is meant to be used with MULTI:
```js
@@ -711,25 +735,25 @@ client.watch("foo", function( err ){
client.get("foo", function(err, result) {
if(err) throw err;
-
+
// Process result
// Heavy and time consuming operation here
client.multi()
.set("foo", "some heavy computation")
.exec(function(err, results) {
-
+
/**
- * If err is null, it means Redis successfully attempted
+ * If err is null, it means Redis successfully attempted
* the operation.
- */
+ */
if(err) throw err;
-
+
/**
* If results === null, it means that a concurrent client
- * changed the key while we were processing it and thus
+ * changed the key while we were processing it and thus
* the execution of the MULTI command was not performed.
- *
+ *
* NOTICE: Failing an execution of MULTI is not considered
* an error. So you will have err === null and results === null
*/
@@ -741,11 +765,11 @@ client.watch("foo", function( err ){
The above snippet shows the correct usage of `watch` with `multi`. Every time a
watched key is changed before the execution of a `multi` command, the execution
-will return `null`. On a normal situation, the execution will return an array of
-values with the results of the operations.
+will return `null`. On a normal situation, the execution will return an array of
+values with the results of the operations.
As stated in the snippet, failing the execution of a `multi` command being watched
-is not considered an error. The execution may return an error if, for example, the
+is not considered an error. The execution may return an error if, for example, the
client cannot connect to Redis.
An example where we can see the execution of a `multi` command fail is as follows:
@@ -759,7 +783,7 @@ clients.watcher.watch('foo',function(err) {
if (err) { throw err; }
//if you comment out the next line, the transaction will work
clients.alterer.set('foo',Math.random(), (err) => {if (err) { throw err; }});
-
+
//using a setTimeout here to ensure that the MULTI/EXEC will come after the SET.
//Normally, you would use a callback to ensure order, but I want the above SET command
//to be easily comment-out-able.
@@ -769,7 +793,7 @@ clients.watcher.watch('foo',function(err) {
.set('foo','abc')
.set('bar','1234')
.exec((err,results) => {
- if (err) { throw err; }
+ if (err) { throw err; }
if (results === null) {
console.log('transaction aborted because results were null');
} else {
@@ -784,7 +808,7 @@ clients.watcher.watch('foo',function(err) {
### WATCH limitations
-Redis WATCH works only on *whole* key values. For example, with WATCH you can
+Redis WATCH works only on _whole_ key values. For example, with WATCH you can
watch a hash for modifications, but you cannot watch a specific field of a hash.
The following example would watch the keys `foo` and `hello`, not the field `hello`
@@ -797,22 +821,22 @@ var redis = require("redis"),
client.hget( "foo", "hello", function(err, result){
//Do some processing with the value from this field and watch it after
-
+
client.watch("foo", "hello", function( err ){
if(err) throw err;
/**
* WRONG: This is now watching the keys 'foo' and 'hello'. It is not
* watching the field 'hello' of hash 'foo'. Because the key 'foo'
- * refers to a hash, this command is now watching the entire hash
- * for modifications.
- */
+ * refers to a hash, this command is now watching the entire hash
+ * for modifications.
+ */
});
} )
```
-This limitation also applies to sets ( cannot watch individual set members )
+This limitation also applies to sets ( cannot watch individual set members )
and any other collections.
## Monitor mode
@@ -829,14 +853,14 @@ arguments and the raw monitoring string.
Example:
```js
-var client = require("redis").createClient();
-client.monitor(function (err, res) {
- console.log("Entering monitoring mode.");
+var client = require('redis').createClient();
+client.monitor(function(err, res) {
+ console.log('Entering monitoring mode.');
});
client.set('foo', 'bar');
-client.on("monitor", function (time, args, raw_reply) {
- console.log(time + ": " + args); // 1458910076.446514:['set', 'foo', 'bar']
+client.on('monitor', function(time, args, raw_reply) {
+ console.log(time + ': ' + args); // 1458910076.446514:['set', 'foo', 'bar']
});
```
@@ -862,12 +886,12 @@ easy comparison.
A handy callback function for displaying return values when testing. Example:
```js
-var redis = require("redis"),
- client = redis.createClient();
+var redis = require('redis'),
+ client = redis.createClient();
-client.on("connect", function () {
- client.set("foo_rand000000000000", "some fantastic value", redis.print);
- client.get("foo_rand000000000000", redis.print);
+client.on('connect', function() {
+ client.set('foo_rand000000000000', 'some fantastic value', redis.print);
+ client.get('foo_rand000000000000', redis.print);
});
```
@@ -885,7 +909,10 @@ the second word as first parameter:
```js
client.script('load', 'return 1');
-client.multi().script('load', 'return 1').exec();
+client
+ .multi()
+ .script('load', 'return 1')
+ .exec();
client.multi([['script', 'load', 'return 1']]).exec();
```
@@ -898,33 +925,35 @@ returns it in the callback. If an error occurs in the meanwhile, that is going
to return an error instead in the callback.
One example of when to use duplicate() would be to accommodate the connection-
-blocking redis commands BRPOP, BLPOP, and BRPOPLPUSH. If these commands
+blocking redis commands BRPOP, BLPOP, and BRPOPLPUSH. If these commands
are used on the same redisClient instance as non-blocking commands, the
non-blocking ones may be queued up until after the blocking ones finish.
```js
-var Redis=require('redis');
+var Redis = require('redis');
var client = Redis.createClient();
var clientBlocking = client.duplicate();
var get = function() {
- console.log("get called");
- client.get("any_key",function() { console.log("get returned"); });
- setTimeout( get, 1000 );
+ console.log('get called');
+ client.get('any_key', function() {
+ console.log('get returned');
+ });
+ setTimeout(get, 1000);
};
var brpop = function() {
- console.log("brpop called");
- clientBlocking.brpop("nonexistent", 5, function() {
- console.log("brpop return");
- setTimeout( brpop, 1000 );
- });
+ console.log('brpop called');
+ clientBlocking.brpop('nonexistent', 5, function() {
+ console.log('brpop return');
+ setTimeout(brpop, 1000);
+ });
};
get();
brpop();
```
Another reason to use duplicate() is when multiple DBs on the same server are
-accessed via the redis SELECT command. Each DB could use its own connection.
+accessed via the redis SELECT command. Each DB could use its own connection.
## client.send_command(command_name[, [args][, callback]])
@@ -960,32 +989,34 @@ commands.
### Commands with Optional and Keyword arguments
-This applies to anything that uses an optional `[WITHSCORES]` or `[LIMIT offset
-count]` in the [redis.io/commands](http://redis.io/commands) documentation.
+This applies to anything that uses an optional `[WITHSCORES]` or `[LIMIT offset count]` in the [redis.io/commands](http://redis.io/commands) documentation.
Example:
```js
-var args = [ 'myzset', 1, 'one', 2, 'two', 3, 'three', 99, 'ninety-nine' ];
-client.zadd(args, function (err, response) {
+var args = ['myzset', 1, 'one', 2, 'two', 3, 'three', 99, 'ninety-nine'];
+client.zadd(args, function(err, response) {
+ if (err) throw err;
+ console.log('added ' + response + ' items.');
+
+ // -Infinity and +Infinity also work
+ var args1 = ['myzset', '+inf', '-inf'];
+ client.zrevrangebyscore(args1, function(err, response) {
if (err) throw err;
- console.log('added '+response+' items.');
+ console.log('example1', response);
+ // write your code here
+ });
- // -Infinity and +Infinity also work
- var args1 = [ 'myzset', '+inf', '-inf' ];
- client.zrevrangebyscore(args1, function (err, response) {
- if (err) throw err;
- console.log('example1', response);
- // write your code here
- });
-
- var max = 3, min = 1, offset = 1, count = 2;
- var args2 = [ 'myzset', max, min, 'WITHSCORES', 'LIMIT', offset, count ];
- client.zrevrangebyscore(args2, function (err, response) {
- if (err) throw err;
- console.log('example2', response);
- // write your code here
- });
+ var max = 3,
+ min = 1,
+ offset = 1,
+ count = 2;
+ var args2 = ['myzset', max, min, 'WITHSCORES', 'LIMIT', offset, count];
+ client.zrevrangebyscore(args2, function(err, response) {
+ if (err) throw err;
+ console.log('example2', response);
+ // write your code here
+ });
});
```
@@ -1031,7 +1062,7 @@ clients: 1, NodeJS: 6.2.0, Redis: 3.2.0, parser: javascript, connected by: tcp
GET 4MiB str, batch 20/1 avg/max: 101.61/118.11 2541ms total, 197 ops/sec
GET 4MiB buf, 1/1 avg/max: 2.32/ 14.93 2502ms total, 430 ops/sec
GET 4MiB buf, batch 20/1 avg/max: 65.01/ 84.72 2536ms total, 308 ops/sec
- ```
+```
## Debugging
@@ -1045,14 +1076,17 @@ application in development mode instead (`NODE_ENV=development`).
Good stack traces are only activated in development and debug mode as this
results in a significant performance penalty.
-___Comparison___:
+**_Comparison_**:
Useless stack trace:
+
```
ReplyError: ERR wrong number of arguments for 'set' command
at parseError (/home/ruben/repos/redis/node_modules/redis-parser/lib/parser.js:158:12)
at parseType (/home/ruben/repos/redis/node_modules/redis-parser/lib/parser.js:219:14)
```
+
Good stack trace:
+
```
ReplyError: ERR wrong number of arguments for 'set' command
at new Command (/home/ruben/repos/redis/lib/command.js:9:902)
diff --git a/package.json b/package.json
index e322fc6ef4..13f610f7d4 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,7 @@
},
"dependencies": {
"denque": "^1.4.1",
+ "prettier": "^1.19.1",
"redis-commands": "^1.5.0",
"redis-errors": "^1.2.0",
"redis-parser": "^3.0.0"
From 7ce08584563184640dafdfd4ab23a32b339a66d2 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 02:28:12 +0000
Subject: [PATCH 62/96] docs
---
.prettierrc | 2 +-
CHANGELOG.md | 661 ++++++++++++++++++++++++++-------------------------
README.md | 277 ++++++++-------------
3 files changed, 436 insertions(+), 504 deletions(-)
diff --git a/.prettierrc b/.prettierrc
index 951c38fd13..1ca516a86c 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -3,7 +3,7 @@
"trailingComma": "all",
"useTabs": false,
"semi": true,
- "singleQuote": true,
+ "singleQuote": false,
"bracketSpacing": true,
"jsxBracketSameLine": false,
"tabWidth": 2,
diff --git a/CHANGELOG.md b/CHANGELOG.md
index daea8eeefc..49be75d7d1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,35 +1,35 @@
# Changelog
-## v.3.0.0 - 09 Feb, 2020
+## v3.0.0 - 09 Feb, 2020
-This version is mainly a release to distribute all the unreleased changes on master since 2017 and additionally removes
+This version is mainly a release to distribute all the unreleased changes on master since 2017 and additionally removes
a lot of old deprecated features and old internals in preparation for an upcoming modernization refactor (v4).
### Breaking Changes
- - Dropped support for Node.js < 6
- - Dropped support for `hiredis` (no longer required)
- - Removed previously deprecated `drain` event
- - Removed previously deprecated `idle` event
- - Removed previously deprecated `parser` option
- - Removed previously deprecated `max_delay` option
- - Removed previously deprecated `max_attempts` option
- - Removed previously deprecated `socket_no_delay` option
+- Dropped support for Node.js < 6
+- Dropped support for `hiredis` (no longer required)
+- Removed previously deprecated `drain` event
+- Removed previously deprecated `idle` event
+- Removed previously deprecated `parser` option
+- Removed previously deprecated `max_delay` option
+- Removed previously deprecated `max_attempts` option
+- Removed previously deprecated `socket_no_delay` option
### Bug Fixes
- - Removed development files from published package (#1370)
- - Duplicate function now allows db param to be passed (#1311)
+- Removed development files from published package (#1370)
+- Duplicate function now allows db param to be passed (#1311)
### Features
- - Upgraded to latest `redis-commands` package
- - Upgraded to latest `redis-parser` package, v3.0.0, which brings performance improvements
- - Replaced `double-ended-queue` with `denque`, which brings performance improvements
- - Add timestamps to debug traces
- - Add `socket_initial_delay` option for `socket.setKeepAlive` (#1396)
-
-## v.2.8.0 - 31 Jul, 2017
+- Upgraded to latest `redis-commands` package
+- Upgraded to latest `redis-parser` package, v3.0.0, which brings performance improvements
+- Replaced `double-ended-queue` with `denque`, which brings performance improvements
+- Add timestamps to debug traces
+- Add `socket_initial_delay` option for `socket.setKeepAlive` (#1396)
+
+## v2.8.0 - 31 Jul, 2017
Features
@@ -42,13 +42,13 @@ Bugfixes
- Fixed emitting internal errors while reconnecting with auth
- Fixed crashing with invalid url option
-## v.2.7.1 - 14 Mar, 2017
+## v2.7.1 - 14 Mar, 2017
Bugfixes
- Fixed monitor mode not working in combination with IPv6 (2.6.0 regression)
-## v.2.7.0 - 11 Mar, 2017
+## v2.7.0 - 11 Mar, 2017
Features
@@ -59,160 +59,160 @@ Bugfixes
- Fixed rename_commands not accepting `null` as value
- Fixed `AbortError`s and `AggregateError`s not showing the error message in the stack trace
-## v.2.6.5 - 15 Jan, 2017
+## v2.6.5 - 15 Jan, 2017
Bugfixes
- Fixed parser not being reset in case the redis connection closed ASAP for overcoming of output buffer limits
- Fixed parser reset if (p)message_buffer listener is attached
-## v.2.6.4 - 12 Jan, 2017
+## v2.6.4 - 12 Jan, 2017
Bugfixes
- Fixed monitor mode not working in combination with IPv6, sockets or lua scripts (2.6.0 regression)
-## v.2.6.3 - 31 Oct, 2016
+## v2.6.3 - 31 Oct, 2016
Bugfixes
- Do not change the tls setting to camel_case
- Fix domain handling in combination with the offline queue (2.5.3 regression)
-## v.2.6.2 - 16 Jun, 2016
+## v2.6.2 - 16 Jun, 2016
Bugfixes
- Fixed individual callbacks of a transaction not being called (2.6.0 regression)
-## v.2.6.1 - 02 Jun, 2016
+## v2.6.1 - 02 Jun, 2016
Bugfixes
- Fixed invalid function name being exported
-## v.2.6.0 - 01 Jun, 2016
+## v2.6.0 - 01 Jun, 2016
In addition to the pre-releases the following changes exist in v.2.6.0:
Features
-- Updated [redis-parser](https://github.com/NodeRedis/node-redis-parser) dependency ([changelog](https://github.com/NodeRedis/node-redis-parser/releases/tag/v.2.0.0))
- - The JS parser is from now on the new default as it is a lot faster than the hiredis parser
- - 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.
-- Added name property to all Redis functions (Node.js >= 4.0)
-- Improved stack traces in development and debug mode
+- Updated [redis-parser](https://github.com/NodeRedis/node-redis-parser) dependency ([changelog](https://github.com/NodeRedis/node-redis-parser/releases/tag/v.2.0.0))
+- The JS parser is from now on the new default as it is a lot faster than the hiredis parser
+- 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.
+- Added name property to all Redis functions (Node.js >= 4.0)
+- Improved stack traces in development and debug mode
Bugfixes
-- Reverted support for `__proto__` (v.2.6.0-2) to prevent and breaking change
+- Reverted support for `__proto__` (v.2.6.0-2) to prevent and breaking change
Deprecations
-- 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
+- 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
-## v.2.6.0-2 - 29 Apr, 2016
+## v2.6.0-2 - 29 Apr, 2016
Features
-- Added support for the new [CLIENT REPLY ON|OFF|SKIP](http://redis.io/commands/client-reply) command (Redis v.3.2)
-- Added support for camelCase
- - The Node.js landscape default is to use camelCase. node_redis is a bit out of the box here
- but from now on it is possible to use both, just as you prefer!
- - If there's any documented variable missing as camelCased, please open a issue for it
-- Improve error handling significantly
- - Only emit an error if the error has not already been handled in a callback
- - Improved unspecific error messages e.g. "Connection gone from end / close event"
- - Added `args` to command errors to improve identification of the error
- - Added origin to errors if there's e.g. a connection error
- - Added ReplyError class. All Redis errors are from now on going to be of that class
- - Added AbortError class. A subclass of AbortError. All unresolved and by node_redis rejected commands are from now on of that class
- - Added AggregateError class. If a unresolved and by node_redis rejected command has no callback and
- this applies to more than a single command, the errors for the commands without callback are aggregated
- to a single error that is emitted in debug_mode in that case.
-- Added `message_buffer` / `pmessage_buffer` events. That event is always going to emit a buffer
- - Listening to the `message` event at the same time is always going to return the same message as string
-- Added callback option to the duplicate function
-- Added support for `__proto__` and other reserved keywords as hgetall field
-- Updated [redis-commands](https://github.com/NodeRedis/redis-commands) dependency ([changelog](https://github.com/NodeRedis/redis-commands/releases/tag/v.1.2.0))
+- Added support for the new [CLIENT REPLY ON|OFF|SKIP](http://redis.io/commands/client-reply) command (Redis v.3.2)
+- Added support for camelCase
+- The Node.js landscape default is to use camelCase. node_redis is a bit out of the box here
+ but from now on it is possible to use both, just as you prefer!
+- If there's any documented variable missing as camelCased, please open a issue for it
+- Improve error handling significantly
+- Only emit an error if the error has not already been handled in a callback
+- Improved unspecific error messages e.g. "Connection gone from end / close event"
+- Added `args` to command errors to improve identification of the error
+- Added origin to errors if there's e.g. a connection error
+- Added ReplyError class. All Redis errors are from now on going to be of that class
+- Added AbortError class. A subclass of AbortError. All unresolved and by node_redis rejected commands are from now on of that class
+- Added AggregateError class. If a unresolved and by node_redis rejected command has no callback and
+ this applies to more than a single command, the errors for the commands without callback are aggregated
+ to a single error that is emitted in debug_mode in that case.
+- Added `message_buffer` / `pmessage_buffer` events. That event is always going to emit a buffer
+- Listening to the `message` event at the same time is always going to return the same message as string
+- Added callback option to the duplicate function
+- Added support for `__proto__` and other reserved keywords as hgetall field
+- Updated [redis-commands](https://github.com/NodeRedis/redis-commands) dependency ([changelog](https://github.com/NodeRedis/redis-commands/releases/tag/v.1.2.0))
Bugfixes
-- Fixed v.2.5.0 auth command regression (under special circumstances a reconnect would not authenticate properly)
-- Fixed v.2.6.0-0 pub sub mode and quit command regressions:
- - Entering pub sub mode not working if a earlier called and still running command returned an error
- - Unsubscribe callback not called if unsubscribing from all channels and resubscribing right away
- - Quit command resulting in an error in some cases
-- Fixed special handled functions in batch and multi context not working the same as without (e.g. select and info)
- - Be aware that not all commands work in combination with transactions but they all work with batch
-- Fixed address always set to 127.0.0.1:6379 in case host / port is set in the `tls` options instead of the general options
+- Fixed v.2.5.0 auth command regression (under special circumstances a reconnect would not authenticate properly)
+- Fixed v.2.6.0-0 pub sub mode and quit command regressions:
+- Entering pub sub mode not working if a earlier called and still running command returned an error
+- Unsubscribe callback not called if unsubscribing from all channels and resubscribing right away
+- Quit command resulting in an error in some cases
+- Fixed special handled functions in batch and multi context not working the same as without (e.g. select and info)
+- Be aware that not all commands work in combination with transactions but they all work with batch
+- Fixed address always set to 127.0.0.1:6379 in case host / port is set in the `tls` options instead of the general options
-## v.2.6.0-1 - 01 Apr, 2016
+## v2.6.0-1 - 01 Apr, 2016
A second pre-release with further fixes. This is likely going to be released as 2.6.0 stable without further changes.
Features
-- Added type validations for client.send_command arguments
+- Added type validations for client.send_command arguments
Bugfixes
-- Fixed client.send_command not working properly with every command and every option
-- Fixed pub sub mode unsubscribing from all channels in combination with the new `string_numbers` option crashing
-- Fixed pub sub mode unsubscribing from all channels not respected while reconnecting
-- Fixed pub sub mode events in combination with the `string_numbers` option emitting the number of channels not as number
+- Fixed client.send_command not working properly with every command and every option
+- Fixed pub sub mode unsubscribing from all channels in combination with the new `string_numbers` option crashing
+- Fixed pub sub mode unsubscribing from all channels not respected while reconnecting
+- Fixed pub sub mode events in combination with the `string_numbers` option emitting the number of channels not as number
-## v.2.6.0-0 - 27 Mar, 2016
+## v2.6.0-0 - 27 Mar, 2016
This is mainly a very important bug fix release with some smaller features.
Features
-- Monitor and pub sub mode now work together with the offline queue
- - All commands that were send after a connection loss are now going to be send after reconnecting
-- Activating monitor mode does now work together with arbitrary commands including pub sub mode
-- Pub sub mode is completely rewritten and all known issues fixed
-- Added `string_numbers` option to get back strings instead of numbers
-- Quit command is from now on always going to end the connection properly
+- Monitor and pub sub mode now work together with the offline queue
+- All commands that were send after a connection loss are now going to be send after reconnecting
+- Activating monitor mode does now work together with arbitrary commands including pub sub mode
+- Pub sub mode is completely rewritten and all known issues fixed
+- Added `string_numbers` option to get back strings instead of numbers
+- Quit command is from now on always going to end the connection properly
Bugfixes
-- Fixed calling monitor command while other commands are still running
-- Fixed monitor and pub sub mode not working together
-- Fixed monitor mode not working in combination with the offline queue
-- Fixed pub sub mode not working in combination with the offline queue
-- Fixed pub sub mode resubscribing not working with non utf8 buffer channels
-- Fixed pub sub mode crashing if calling unsubscribe / subscribe in various combinations
-- Fixed pub sub mode emitting unsubscribe even if no channels were unsubscribed
-- Fixed pub sub mode emitting a message without a message published
-- Fixed quit command not ending the connection and resulting in further reconnection if called while reconnecting
+- Fixed calling monitor command while other commands are still running
+- Fixed monitor and pub sub mode not working together
+- Fixed monitor mode not working in combination with the offline queue
+- Fixed pub sub mode not working in combination with the offline queue
+- Fixed pub sub mode resubscribing not working with non utf8 buffer channels
+- Fixed pub sub mode crashing if calling unsubscribe / subscribe in various combinations
+- Fixed pub sub mode emitting unsubscribe even if no channels were unsubscribed
+- Fixed pub sub mode emitting a message without a message published
+- Fixed quit command not ending the connection and resulting in further reconnection if called while reconnecting
The quit command did not end connections earlier if the connection was down at that time and this could have
lead to strange situations, therefor this was fixed to end the connection right away in those cases.
-## v.2.5.3 - 21 Mar, 2016
+## v2.5.3 - 21 Mar, 2016
Bugfixes
-- Revert throwing on invalid data types and print a warning instead
+- Revert throwing on invalid data types and print a warning instead
-## v.2.5.2 - 16 Mar, 2016
+## v2.5.2 - 16 Mar, 2016
Bugfixes
-- Fixed breaking changes against Redis 2.4 introduced in 2.5.0 / 2.5.1
+- Fixed breaking changes against Redis 2.4 introduced in 2.5.0 / 2.5.1
-## v.2.5.1 - 15 Mar, 2016
+## v2.5.1 - 15 Mar, 2016
Bugfixes
-- Fixed info command not working anymore with optional section argument
+- Fixed info command not working anymore with optional section argument
-## v.2.5.0 - 15 Mar, 2016
+## v2.5.0 - 15 Mar, 2016
Same changelog as the pre-release
-## v.2.5.0-1 - 07 Mar, 2016
+## v2.5.0-1 - 07 Mar, 2016
This is a big release with some substantial underlining changes. Therefor this is released as a pre-release and I encourage anyone who's able to, to test this out.
@@ -222,173 +222,173 @@ This release is also going to deprecate a couple things to prepare for a future
Features
-- The parsers moved into the [redis-parser](https://github.com/NodeRedis/node-redis-parser) module and will be maintained in there from now on
- - Improve js parser speed significantly for big SUNION/SINTER/LRANGE/ZRANGE
-- Improve redis-url parsing to also accept the database-number and options as query parameters as suggested in [IANA](http://www.iana.org/assignments/uri-schemes/prov/redis)
-- Added a `retry_unfulfilled_commands` option
- - Setting this to 'true' results in retrying all commands that were not fulfilled on a connection loss after the reconnect. Use with caution
-- Added a `db` option to select the database while connecting (this is [not recommended](https://groups.google.com/forum/#!topic/redis-db/vS5wX8X4Cjg))
-- Added a `password` option as alias for auth_pass
-- The client.server_info is from now on updated while using the info command
-- Gracefuly handle redis protocol errors from now on
-- Added a `warning` emitter that receives node_redis warnings like auth not required and deprecation messages
-- Added a `retry_strategy` option that replaces all reconnect options
-- The reconnecting event from now on also receives:
- - The error message why the reconnect happened (params.error)
- - The amount of times the client was connected (params.times_connected)
- - The total reconnecting time since the last time connected (params.total_retry_time)
-- Always respect the command execution order no matter if the reply could be returned sync or not (former exceptions: [#937](https://github.com/NodeRedis/node_redis/issues/937#issuecomment-167525939))
-- redis.createClient is now checking input values stricter and detects more faulty input
-- Started refactoring internals into individual modules
-- Pipelining speed improvements
+- The parsers moved into the [redis-parser](https://github.com/NodeRedis/node-redis-parser) module and will be maintained in there from now on
+- Improve js parser speed significantly for big SUNION/SINTER/LRANGE/ZRANGE
+- Improve redis-url parsing to also accept the database-number and options as query parameters as suggested in [IANA](http://www.iana.org/assignments/uri-schemes/prov/redis)
+- Added a `retry_unfulfilled_commands` option
+- Setting this to 'true' results in retrying all commands that were not fulfilled on a connection loss after the reconnect. Use with caution
+- Added a `db` option to select the database while connecting (this is [not recommended](https://groups.google.com/forum/#!topic/redis-db/vS5wX8X4Cjg))
+- Added a `password` option as alias for auth_pass
+- The client.server_info is from now on updated while using the info command
+- Gracefuly handle redis protocol errors from now on
+- Added a `warning` emitter that receives node_redis warnings like auth not required and deprecation messages
+- Added a `retry_strategy` option that replaces all reconnect options
+- The reconnecting event from now on also receives:
+- The error message why the reconnect happened (params.error)
+- The amount of times the client was connected (params.times_connected)
+- The total reconnecting time since the last time connected (params.total_retry_time)
+- Always respect the command execution order no matter if the reply could be returned sync or not (former exceptions: [#937](https://github.com/NodeRedis/node_redis/issues/937#issuecomment-167525939))
+- redis.createClient is now checking input values stricter and detects more faulty input
+- Started refactoring internals into individual modules
+- Pipelining speed improvements
Bugfixes
-- Fixed explicit undefined as a command callback in a multi context
-- Fixed hmset failing to detect the first key as buffer or date if the key is of that type
-- Fixed do not run toString on an array argument and throw a "invalid data" error instead
- - This is not considered as breaking change, as this is likely a error in your code and if you want to have such a behavior you should handle this beforehand
- - The same applies to Map / Set and individual Object types
-- Fixed redis url not accepting the protocol being omitted or protocols other than the redis protocol for convenience
-- Fixed parsing the db keyspace even if the first database does not begin with a zero
-- Fixed handling of errors occurring while receiving pub sub messages
-- Fixed huge string pipelines crashing NodeJS (Pipeline size above 256mb)
-- Fixed rename_commands and prefix option not working together
-- Fixed ready being emitted to early in case a slave is still syncing / master down
+- Fixed explicit undefined as a command callback in a multi context
+- Fixed hmset failing to detect the first key as buffer or date if the key is of that type
+- Fixed do not run toString on an array argument and throw a "invalid data" error instead
+- This is not considered as breaking change, as this is likely a error in your code and if you want to have such a behavior you should handle this beforehand
+- The same applies to Map / Set and individual Object types
+- Fixed redis url not accepting the protocol being omitted or protocols other than the redis protocol for convenience
+- Fixed parsing the db keyspace even if the first database does not begin with a zero
+- Fixed handling of errors occurring while receiving pub sub messages
+- Fixed huge string pipelines crashing NodeJS (Pipeline size above 256mb)
+- Fixed rename_commands and prefix option not working together
+- Fixed ready being emitted to early in case a slave is still syncing / master down
Deprecations
-- Using any command with a argument being set to null or undefined is deprecated
- - From v.3.0.0 on using a command with such an argument will return an error instead
- - If you want to keep the old behavior please use a precheck in your code that converts the arguments to a string.
- - Using SET or SETEX with a undefined or null value will from now on also result in converting the value to "null" / "undefined" to have a consistent behavior. This is not considered as breaking change, as it returned an error earlier.
-- Using .end(flush) without the flush parameter is deprecated and the flush parameter should explicitly be used
- - From v.3.0.0 on using .end without flush will result in an error
- - Using .end without flush means that any command that did not yet return is going to silently fail. Therefor this is considered harmful and you should explicitly silence such errors if you are sure you want this
-- Depending on the return value of a command to detect the backpressure is deprecated
- - From version 3.0.0 on node_redis might not return true / false as a return value anymore. Please rely on client.should_buffer instead
-- The `socket_nodelay` option is deprecated and will be removed in v.3.0.0
- - If you want to buffer commands you should use [.batch or .multi](./README.md) instead. This is necessary to reduce the amount of different options and this is very likely reducing your throughput if set to false.
- - If you are sure you want to activate the NAGLE algorithm you can still activate it by using client.stream.setNoDelay(false)
-- The `max_attempts` option is deprecated and will be removed in v.3.0.0. Please use the `retry_strategy` instead
-- The `retry_max_delay` option is deprecated and will be removed in v.3.0.0. Please use the `retry_strategy` instead
-- The drain event is deprecated and will be removed in v.3.0.0. Please listen to the stream drain event instead
-- The idle event is deprecated and will likely be removed in v.3.0.0. If you rely on this feature please open a new ticket in node_redis with your use case
-- Redis < v. 2.6 is not officially supported anymore and might not work in all cases. Please update to a newer redis version as it is not possible to test for these old versions
-- Removed non documented command syntax (adding the callback to an arguments array instead of passing it as individual argument)
+- Using any command with a argument being set to null or undefined is deprecated
+- From v.3.0.0 on using a command with such an argument will return an error instead
+- If you want to keep the old behavior please use a precheck in your code that converts the arguments to a string.
+- Using SET or SETEX with a undefined or null value will from now on also result in converting the value to "null" / "undefined" to have a consistent behavior. This is not considered as breaking change, as it returned an error earlier.
+- Using .end(flush) without the flush parameter is deprecated and the flush parameter should explicitly be used
+- From v.3.0.0 on using .end without flush will result in an error
+- Using .end without flush means that any command that did not yet return is going to silently fail. Therefor this is considered harmful and you should explicitly silence such errors if you are sure you want this
+- Depending on the return value of a command to detect the backpressure is deprecated
+- From version 3.0.0 on node_redis might not return true / false as a return value anymore. Please rely on client.should_buffer instead
+- The `socket_nodelay` option is deprecated and will be removed in v.3.0.0
+- If you want to buffer commands you should use [.batch or .multi](./README.md) instead. This is necessary to reduce the amount of different options and this is very likely reducing your throughput if set to false.
+- If you are sure you want to activate the NAGLE algorithm you can still activate it by using client.stream.setNoDelay(false)
+- The `max_attempts` option is deprecated and will be removed in v.3.0.0. Please use the `retry_strategy` instead
+- The `retry_max_delay` option is deprecated and will be removed in v.3.0.0. Please use the `retry_strategy` instead
+- The drain event is deprecated and will be removed in v.3.0.0. Please listen to the stream drain event instead
+- The idle event is deprecated and will likely be removed in v.3.0.0. If you rely on this feature please open a new ticket in node_redis with your use case
+- Redis < v. 2.6 is not officially supported anymore and might not work in all cases. Please update to a newer redis version as it is not possible to test for these old versions
+- Removed non documented command syntax (adding the callback to an arguments array instead of passing it as individual argument)
-## v.2.4.2 - 27 Nov, 2015
+## v2.4.2 - 27 Nov, 2015
Bugfixes
-- Fixed not emitting ready after reconnect with disable_resubscribing ([@maxgalbu](https://github.com/maxgalbu))
+- Fixed not emitting ready after reconnect with disable_resubscribing ([@maxgalbu](https://github.com/maxgalbu))
-## v.2.4.1 - 25 Nov, 2015
+## v2.4.1 - 25 Nov, 2015
Bugfixes
-- Fixed a js parser regression introduced in 2.4.0 ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed a js parser regression introduced in 2.4.0 ([@BridgeAR](https://github.com/BridgeAR))
-## v.2.4.0 - 25 Nov, 2015
+## v2.4.0 - 25 Nov, 2015
Features
-- Added `tls` option to initiate a connection to a redis server behind a TLS proxy. Thanks ([@paddybyers](https://github.com/paddybyers))
-- Added `prefix` option to auto key prefix any command with the provided prefix ([@luin](https://github.com/luin) & [@BridgeAR](https://github.com/BridgeAR))
-- Added `url` option to pass the connection url with the options object ([@BridgeAR](https://github.com/BridgeAR))
-- Added `client.duplicate([options])` to duplicate the current client and return a new one with the same options ([@BridgeAR](https://github.com/BridgeAR))
-- Improve performance by up to 20% on almost all use cases ([@BridgeAR](https://github.com/BridgeAR))
+- Added `tls` option to initiate a connection to a redis server behind a TLS proxy. Thanks ([@paddybyers](https://github.com/paddybyers))
+- Added `prefix` option to auto key prefix any command with the provided prefix ([@luin](https://github.com/luin) & [@BridgeAR](https://github.com/BridgeAR))
+- Added `url` option to pass the connection url with the options object ([@BridgeAR](https://github.com/BridgeAR))
+- Added `client.duplicate([options])` to duplicate the current client and return a new one with the same options ([@BridgeAR](https://github.com/BridgeAR))
+- Improve performance by up to 20% on almost all use cases ([@BridgeAR](https://github.com/BridgeAR))
Bugfixes
-- Fixed js parser handling big values slow ([@BridgeAR](https://github.com/BridgeAR))
- - The speed is now on par with the hiredis parser.
+- Fixed js parser handling big values slow ([@BridgeAR](https://github.com/BridgeAR))
+- The speed is now on par with the hiredis parser.
-## v.2.3.1 - 18 Nov, 2015
+## v2.3.1 - 18 Nov, 2015
Bugfixes
-- Fixed saving buffers with charsets other than utf-8 while using multi ([@BridgeAR](https://github.com/BridgeAR))
-- Fixed js parser handling big values very slow ([@BridgeAR](https://github.com/BridgeAR))
- - The speed is up to ~500% faster than before but still up to ~50% slower than the hiredis parser.
+- Fixed saving buffers with charsets other than utf-8 while using multi ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed js parser handling big values very slow ([@BridgeAR](https://github.com/BridgeAR))
+- The speed is up to ~500% faster than before but still up to ~50% slower than the hiredis parser.
-## v.2.3.0 - 30 Oct, 2015
+## v2.3.0 - 30 Oct, 2015
Features
-- Improve speed further for: ([@BridgeAR](https://github.com/BridgeAR))
- - saving big strings (up to +300%)
- - using .multi / .batch (up to +50% / on Node.js 0.10.x +300%)
- - saving small buffers
-- Increased coverage to 99% ([@BridgeAR](https://github.com/BridgeAR))
-- Refactored manual backpressure control ([@BridgeAR](https://github.com/BridgeAR))
- - Removed the high water mark and low water mark. Such a mechanism should be implemented by a user instead
- - The `drain` event is from now on only emitted if the stream really had to buffer
-- Reduced the default connect_timeout to be one hour instead of 24h ([@BridgeAR](https://github.com/BridgeAR))
-- Added .path to redis.createClient(options); ([@BridgeAR](https://github.com/BridgeAR))
-- Ignore info command, if not available on server ([@ivanB1975](https://github.com/ivanB1975))
+- Improve speed further for: ([@BridgeAR](https://github.com/BridgeAR))
+- saving big strings (up to +300%)
+- using .multi / .batch (up to +50% / on Node.js 0.10.x +300%)
+- saving small buffers
+- Increased coverage to 99% ([@BridgeAR](https://github.com/BridgeAR))
+- Refactored manual backpressure control ([@BridgeAR](https://github.com/BridgeAR))
+- Removed the high water mark and low water mark. Such a mechanism should be implemented by a user instead
+- The `drain` event is from now on only emitted if the stream really had to buffer
+- Reduced the default connect_timeout to be one hour instead of 24h ([@BridgeAR](https://github.com/BridgeAR))
+- Added .path to redis.createClient(options); ([@BridgeAR](https://github.com/BridgeAR))
+- Ignore info command, if not available on server ([@ivanB1975](https://github.com/ivanB1975))
Bugfixes
-- Fixed a js parser error that could result in a timeout ([@BridgeAR](https://github.com/BridgeAR))
-- Fixed .multi / .batch used with Node.js 0.10.x not working properly after a reconnect ([@BridgeAR](https://github.com/BridgeAR))
-- Fixed fired but not yet returned commands not being rejected after a connection loss ([@BridgeAR](https://github.com/BridgeAR))
-- Fixed connect_timeout not respected if no connection has ever been established ([@gagle](https://github.com/gagle) & [@benjie](https://github.com/benjie))
-- Fixed return_buffers in pub sub mode ([@komachi](https://github.com/komachi))
+- Fixed a js parser error that could result in a timeout ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed .multi / .batch used with Node.js 0.10.x not working properly after a reconnect ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed fired but not yet returned commands not being rejected after a connection loss ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed connect_timeout not respected if no connection has ever been established ([@gagle](https://github.com/gagle) & [@benjie](https://github.com/benjie))
+- Fixed return_buffers in pub sub mode ([@komachi](https://github.com/komachi))
-## v.2.2.5 - 18 Oct, 2015
+## v2.2.5 - 18 Oct, 2015
Bugfixes
-- Fixed undefined options passed to a new instance not accepted (possible with individual .createClient functions) ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed undefined options passed to a new instance not accepted (possible with individual .createClient functions) ([@BridgeAR](https://github.com/BridgeAR))
-## v.2.2.4 - 17 Oct, 2015
+## v2.2.4 - 17 Oct, 2015
Bugfixes
-- Fixed unspecific error message for unresolvable commands ([@BridgeAR](https://github.com/BridgeAR))
-- Fixed not allowed command error in pubsub mode not being returned in a provided callback ([@BridgeAR](https://github.com/BridgeAR))
-- Fixed to many commands forbidden in pub sub mode ([@BridgeAR](https://github.com/BridgeAR))
-- Fixed mutation of the arguments array passed to .multi / .batch constructor ([@BridgeAR](https://github.com/BridgeAR))
-- Fixed mutation of the options object passed to createClient ([@BridgeAR](https://github.com/BridgeAR))
-- Fixed error callback in .multi not called if connection in broken mode ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed unspecific error message for unresolvable commands ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed not allowed command error in pubsub mode not being returned in a provided callback ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed to many commands forbidden in pub sub mode ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed mutation of the arguments array passed to .multi / .batch constructor ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed mutation of the options object passed to createClient ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed error callback in .multi not called if connection in broken mode ([@BridgeAR](https://github.com/BridgeAR))
-## v.2.2.3 - 14 Oct, 2015
+## v2.2.3 - 14 Oct, 2015
Bugfixes
-- Fixed multi not being executed on Node 0.10.x if node_redis not yet ready ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed multi not being executed on Node 0.10.x if node_redis not yet ready ([@BridgeAR](https://github.com/BridgeAR))
-## v.2.2.2 - 14 Oct, 2015
+## v2.2.2 - 14 Oct, 2015
Bugfixes
-- Fixed regular commands not being executed after a .multi until .exec was called ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed regular commands not being executed after a .multi until .exec was called ([@BridgeAR](https://github.com/BridgeAR))
-## v.2.2.1 - 12 Oct, 2015
+## v2.2.1 - 12 Oct, 2015
No code change
-## v.2.2.0 - 12 Oct, 2015 - The peregrino falcon
+## v2.2.0 - 12 Oct, 2015 - The peregrino falcon
The peregrino falcon is the fasted bird on earth and this is what this release is all about: Increased performance for heavy usage by up to **400%** [sic!] and increased overall performance for any command as well. Please check the benchmarks in the [README.md](README.md) for further details.
Features
-- Added rename_commands options to handle renamed commands from the redis config ([@digmxl](https://github.com/digmxl) & [@BridgeAR](https://github.com/BridgeAR))
-- Added disable_resubscribing option to prevent a client from resubscribing after reconnecting ([@BridgeAR](https://github.com/BridgeAR))
-- Increased performance ([@BridgeAR](https://github.com/BridgeAR))
- - exchanging built in queue with [@petkaantonov](https://github.com/petkaantonov)'s [double-ended queue](https://github.com/petkaantonov/deque)
- - prevent polymorphism
- - optimize statements
-- Added *.batch* command, similar to .multi but without transaction ([@BridgeAR](https://github.com/BridgeAR))
-- Improved pipelining to minimize the [RTT](http://redis.io/topics/pipelining) further ([@BridgeAR](https://github.com/BridgeAR))
+- Added rename_commands options to handle renamed commands from the redis config ([@digmxl](https://github.com/digmxl) & [@BridgeAR](https://github.com/BridgeAR))
+- Added disable_resubscribing option to prevent a client from resubscribing after reconnecting ([@BridgeAR](https://github.com/BridgeAR))
+- Increased performance ([@BridgeAR](https://github.com/BridgeAR))
+- exchanging built in queue with [@petkaantonov](https://github.com/petkaantonov)'s [double-ended queue](https://github.com/petkaantonov/deque)
+- prevent polymorphism
+- optimize statements
+- Added _.batch_ command, similar to .multi but without transaction ([@BridgeAR](https://github.com/BridgeAR))
+- Improved pipelining to minimize the [RTT](http://redis.io/topics/pipelining) further ([@BridgeAR](https://github.com/BridgeAR))
Bugfixes
-- Fixed a javascript parser regression introduced in 2.0 that could result in timeouts on high load. ([@BridgeAR](https://github.com/BridgeAR))
- - I was not able to write a regression test for this, since the error seems to only occur under heavy load with special conditions. So please have a look for timeouts with the js parser, if you use it and report all issues and switch to the hiredis parser in the meanwhile. If you're able to come up with a reproducable test case, this would be even better :)
-- Fixed should_buffer boolean for .exec, .select and .auth commands not being returned and fix a couple special conditions ([@BridgeAR](https://github.com/BridgeAR))
+- Fixed a javascript parser regression introduced in 2.0 that could result in timeouts on high load. ([@BridgeAR](https://github.com/BridgeAR))
+- I was not able to write a regression test for this, since the error seems to only occur under heavy load with special conditions. So please have a look for timeouts with the js parser, if you use it and report all issues and switch to the hiredis parser in the meanwhile. If you're able to come up with a reproducable test case, this would be even better :)
+- Fixed should_buffer boolean for .exec, .select and .auth commands not being returned and fix a couple special conditions ([@BridgeAR](https://github.com/BridgeAR))
If you do not rely on transactions but want to reduce the RTT you can use .batch from now on. It'll behave just the same as .multi but it does not have any transaction and therefor won't roll back any failed commands.
Both .multi and .batch are from now on going to cache the commands and release them while calling .exec.
@@ -425,29 +425,29 @@ To conclude: we can proudly say that node_redis is very likely outperforming any
Known issues
-- The pub sub system has some flaws and those will be addressed in the next minor release
+- The pub sub system has some flaws and those will be addressed in the next minor release
## v2.1.0 - Oct 02, 2015
Features:
-- Addded optional flush parameter to `.end`. If set to true, commands fired after using .end are going to be rejected instead of being ignored. (@crispy1989)
-- Addded: host and port can now be provided in a single options object. E.g. redis.createClient({ host: 'localhost', port: 1337, max_attempts: 5 }); (@BridgeAR)
-- Speedup common cases (@BridgeAR)
+- Addded optional flush parameter to `.end`. If set to true, commands fired after using .end are going to be rejected instead of being ignored. (@crispy1989)
+- Addded: host and port can now be provided in a single options object. E.g. redis.createClient({ host: 'localhost', port: 1337, max_attempts: 5 }); (@BridgeAR)
+- Speedup common cases (@BridgeAR)
Bugfixes:
-- Fix argument mutation while using the array notation with the multi constructor (@BridgeAR)
-- Fix multi.hmset key not being type converted if used with an object and key not being a string (@BridgeAR)
-- Fix parser errors not being catched properly (@BridgeAR)
-- Fix a crash that could occur if a redis server does not return the info command as usual #541 (@BridgeAR)
-- Explicitly passing undefined as a callback statement will work again. E.g. client.publish('channel', 'message', undefined); (@BridgeAR)
+- Fix argument mutation while using the array notation with the multi constructor (@BridgeAR)
+- Fix multi.hmset key not being type converted if used with an object and key not being a string (@BridgeAR)
+- Fix parser errors not being catched properly (@BridgeAR)
+- Fix a crash that could occur if a redis server does not return the info command as usual #541 (@BridgeAR)
+- Explicitly passing undefined as a callback statement will work again. E.g. client.publish('channel', 'message', undefined); (@BridgeAR)
## v2.0.1 - Sep 24, 2015
Bugfixes:
-- Fix argument mutation while using the array notation in combination with keys / callbacks ([#866](.)). (@BridgeAR)
+- Fix argument mutation while using the array notation in combination with keys / callbacks ([#866](.)). (@BridgeAR)
## v2.0.0 - Sep 21, 2015
@@ -473,7 +473,7 @@ This is the biggest release that node_redis had since it was released in 2010. A
- Added: Network errors and other stream errors will from now on include the error code as `err.code` property (@BridgeAR)
- Added: Errors thrown by redis will now include the redis error code as `err.code` property. (@skeggse & @BridgeAR)
- Added: Errors thrown by node_redis will now include a `err.command` property for the command used (@BridgeAR)
-- Added new commands and drop support for deprecated *substr* (@BridgeAR)
+- Added new commands and drop support for deprecated _substr_ (@BridgeAR)
- Added new possibilities how to provide the command arguments (@BridgeAR)
- The entries in the keyspace of the server_info is now an object instead of a string. (@SinisterLight & @BridgeAR)
- Small speedup here and there (e.g. by not using .toLowerCase() anymore) (@BridgeAR)
@@ -482,7 +482,7 @@ This is the biggest release that node_redis had since it was released in 2010. A
- Remove dead code, clean up and refactor very old chunks (@BridgeAR)
- Don't flush the offline queue if reconnecting (@BridgeAR)
- Emit all errors insteaf of throwing sometimes and sometimes emitting them (@BridgeAR)
-- *auth_pass* passwords are now checked to be a valid password (@jcppman & @BridgeAR)
+- _auth_pass_ passwords are now checked to be a valid password (@jcppman & @BridgeAR)
## Bug fixes:
@@ -512,11 +512,13 @@ This is the biggest release that node_redis had since it was released in 2010. A
2. Error messages have changed quite a bit. If you depend on a specific wording please check your application carfully.
3. Errors are from now on always either returned if a callback is present or emitted. They won't be thrown (neither sync, nor async).
4. The Multi error handling has changed a lot!
- - All errors are from now on errors instead of strings (this only applied to the js parser).
- - If an error occurs while queueing the commands an EXECABORT error will be returned including the failed commands as `.errors` property instead of an array with errors.
- - If an error occurs while executing the commands and that command has a callback it'll return the error as first parameter (`err, undefined` instead of `null, undefined`).
- - All the errors occuring while executing the commands will stay in the result value as error instance (if you used the js parser before they would have been strings). Be aware that the transaction won't be aborted if those error occurr!
- - If `multi.exec` does not have a callback and an EXECABORT error occurrs, it'll emit that error instead.
+
+- All errors are from now on errors instead of strings (this only applied to the js parser).
+- If an error occurs while queueing the commands an EXECABORT error will be returned including the failed commands as `.errors` property instead of an array with errors.
+- If an error occurs while executing the commands and that command has a callback it'll return the error as first parameter (`err, undefined` instead of `null, undefined`).
+- All the errors occuring while executing the commands will stay in the result value as error instance (if you used the js parser before they would have been strings). Be aware that the transaction won't be aborted if those error occurr!
+- If `multi.exec` does not have a callback and an EXECABORT error occurrs, it'll emit that error instead.
+
5. If redis can't connect to your redis server it'll give up after a certain point of failures (either max connection attempts or connection timeout exceeded). If that is the case it'll emit an CONNECTION_BROKEN error. You'll have to initiate a new client to try again afterwards.
6. The offline queue is not flushed anymore on a reconnect. It'll stay until node_redis gives up trying to reach the server or until you close the connection.
7. Before this release node_redis catched user errors and threw them async back. This is not the case anymore! No user behavior of what so ever will be tracked or catched.
@@ -530,110 +532,113 @@ From now on we'll push new releases more frequently out and fix further long out
## v1.0.0 - Aug 30, 2015
-* Huge issue and pull-request cleanup. Thanks Blain! (@blainsmith)
-* [#658](https://github.com/NodeRedis/node_redis/pull/658) Client now parses URL-format connection strings (e.g., redis://foo:pass@127.0.0.1:8080) (@kuwabarahiroshi)
-* [#749](https://github.com/NodeRedis/node_redis/pull/749) Fix reconnection bug when client is in monitoring mode (@danielbprice)
-* [#786](https://github.com/NodeRedis/node_redis/pull/786) Refactor createClient. Fixes #651 (@BridgeAR)
-* [#793](https://github.com/NodeRedis/node_redis/pull/793) Refactor tests and improve test coverage (@erinspice, @bcoe)
-* [#733](https://github.com/NodeRedis/node_redis/pull/733) Fixes detect_buffers functionality in the context of exec. Fixes #732, #263 (@raydog)
-* [#785](https://github.com/NodeRedis/node_redis/pull/785) Tiny speedup by using 'use strict' (@BridgeAR)
-* Fix extraneous error output due to pubsub tests (Mikael Kohlmyr)
+- Huge issue and pull-request cleanup. Thanks Blain! (@blainsmith)
+- [#658](https://github.com/NodeRedis/node_redis/pull/658) Client now parses URL-format connection strings (e.g., redis://foo:pass@127.0.0.1:8080) (@kuwabarahiroshi)
+- [#749](https://github.com/NodeRedis/node_redis/pull/749) Fix reconnection bug when client is in monitoring mode (@danielbprice)
+- [#786](https://github.com/NodeRedis/node_redis/pull/786) Refactor createClient. Fixes #651 (@BridgeAR)
+- [#793](https://github.com/NodeRedis/node_redis/pull/793) Refactor tests and improve test coverage (@erinspice, @bcoe)
+- [#733](https://github.com/NodeRedis/node_redis/pull/733) Fixes detect_buffers functionality in the context of exec. Fixes #732, #263 (@raydog)
+- [#785](https://github.com/NodeRedis/node_redis/pull/785) Tiny speedup by using 'use strict' (@BridgeAR)
+- Fix extraneous error output due to pubsub tests (Mikael Kohlmyr)
## v0.12.1 - Aug 10, 2014
-* Fix IPv6/IPv4 family selection in node 0.11+ (Various)
+
+- Fix IPv6/IPv4 family selection in node 0.11+ (Various)
## v0.12.0 - Aug 9, 2014
-* Fix unix socket support (Jack Tang)
-* Improve createClient argument handling (Jack Tang)
+
+- Fix unix socket support (Jack Tang)
+- Improve createClient argument handling (Jack Tang)
## v0.11.0 - Jul 10, 2014
-* IPv6 Support. (Yann Stephan)
-* Revert error emitting and go back to throwing errors. (Bryce Baril)
-* Set socket_keepalive to prevent long-lived client timeouts. (mohit)
-* Correctly reset retry timer. (ouotuo)
-* Domains protection from bad user exit. (Jake Verbaten)
-* Fix reconnection socket logic to prevent misqueued entries. (Iain Proctor)
+- IPv6 Support. (Yann Stephan)
+- Revert error emitting and go back to throwing errors. (Bryce Baril)
+- Set socket_keepalive to prevent long-lived client timeouts. (mohit)
+- Correctly reset retry timer. (ouotuo)
+- Domains protection from bad user exit. (Jake Verbaten)
+- Fix reconnection socket logic to prevent misqueued entries. (Iain Proctor)
## v0.10.3 - May 22, 2014
-* Update command list to match Redis 2.8.9 (Charles Feng)
+- Update command list to match Redis 2.8.9 (Charles Feng)
## v0.10.2 - May 18, 2014
-* Better binary key handling for HGETALL. (Nick Apperson)
-* Fix test not resetting `error` handler. (CrypticSwarm)
-* Fix SELECT error semantics. (Bryan English)
+- Better binary key handling for HGETALL. (Nick Apperson)
+- Fix test not resetting `error` handler. (CrypticSwarm)
+- Fix SELECT error semantics. (Bryan English)
## v0.10.1 - February 17, 2014
-* Skip plucking redis version from the INFO stream if INFO results weren't provided. (Robert Sköld)
+- Skip plucking redis version from the INFO stream if INFO results weren't provided. (Robert Sköld)
## v0.10.0 - December 21, 2013
-* Instead of throwing errors asynchronously, emit errors on client. (Bryce Baril)
+- Instead of throwing errors asynchronously, emit errors on client. (Bryce Baril)
## v0.9.2 - December 15, 2013
-* Regenerate commands for new 2.8.x Redis commands. (Marek Ventur)
-* Correctly time reconnect counts when using 'auth'. (William Hockey)
+- Regenerate commands for new 2.8.x Redis commands. (Marek Ventur)
+- Correctly time reconnect counts when using 'auth'. (William Hockey)
## v0.9.1 - November 23, 2013
-* Allow hmset to accept numeric keys. (Alex Stokes)
-* Fix TypeError for multiple MULTI/EXEC errors. (Kwangsu Kim)
+- Allow hmset to accept numeric keys. (Alex Stokes)
+- Fix TypeError for multiple MULTI/EXEC errors. (Kwangsu Kim)
## v0.9.0 - October 17, 2013
-* Domains support. (Forrest L Norvell)
+- Domains support. (Forrest L Norvell)
## v0.8.6 - October 2, 2013
-* If error is already an Error, don't wrap it in another Error. (Mathieu M-Gosselin)
-* Fix retry delay logic (Ian Babrou)
-* Return Errors instead of strings where Errors are expected (Ian Babrou)
-* Add experimental `.unref()` method to RedisClient (Bryce Baril / Olivier Lalonde)
-* Strengthen checking of reply to prevent conflating "message" or "pmessage" fields with pub_sub replies. (Bryce Baril)
+- If error is already an Error, don't wrap it in another Error. (Mathieu M-Gosselin)
+- Fix retry delay logic (Ian Babrou)
+- Return Errors instead of strings where Errors are expected (Ian Babrou)
+- Add experimental `.unref()` method to RedisClient (Bryce Baril / Olivier Lalonde)
+- Strengthen checking of reply to prevent conflating "message" or "pmessage" fields with pub_sub replies. (Bryce Baril)
## v0.8.5 - September 26, 2013
-* Add `auth_pass` option to connect and immediately authenticate (Henrik Peinar)
+- Add `auth_pass` option to connect and immediately authenticate (Henrik Peinar)
## v0.8.4 - June 24, 2013
Many contributed features and fixes, including:
-* Ignore password set if not needed. (jbergknoff)
-* Improved compatibility with 0.10.X for tests and client.end() (Bryce Baril)
-* Protect connection retries from application exceptions. (Amos Barreto)
-* Better exception handling for Multi/Exec (Thanasis Polychronakis)
-* Renamed pubsub mode to subscriber mode (Luke Plaster)
-* Treat SREM like SADD when passed an array (Martin Ciparelli)
-* Fix empty unsub/punsub TypeError (Jeff Barczewski)
-* Only attempt to run a callback if it one was provided (jifeng)
+
+- Ignore password set if not needed. (jbergknoff)
+- Improved compatibility with 0.10.X for tests and client.end() (Bryce Baril)
+- Protect connection retries from application exceptions. (Amos Barreto)
+- Better exception handling for Multi/Exec (Thanasis Polychronakis)
+- Renamed pubsub mode to subscriber mode (Luke Plaster)
+- Treat SREM like SADD when passed an array (Martin Ciparelli)
+- Fix empty unsub/punsub TypeError (Jeff Barczewski)
+- Only attempt to run a callback if it one was provided (jifeng)
## v0.8.3 - April 09, 2013
Many contributed features and fixes, including:
-* Fix some tests for Node.js version 0.9.x+ changes (Roman Ivanilov)
-* Fix error when commands submitted after idle event handler (roamm)
-* Bypass Redis for no-op SET/SETEX commands (jifeng)
-* Fix HMGET + detect_buffers (Joffrey F)
-* Fix CLIENT LOAD functionality (Jonas Dohse)
-* Add percentage outputs to diff_multi_bench_output.js (Bryce Baril)
-* Add retry_max_delay option (Tomasz Durka)
-* Fix parser off-by-one errors with nested multi-bulk replies (Bryce Baril)
-* Prevent parser from sinking application-side exceptions (Bryce Baril)
-* Fix parser incorrect buffer skip when parsing multi-bulk errors (Bryce Baril)
-* Reverted previous change with throwing on non-string values with HMSET (David Trejo)
-* Fix command queue sync issue when using pubsub (Tom Leach)
-* Fix compatibility with two-word Redis commands (Jonas Dohse)
-* Add EVAL with array syntax (dmoena)
-* Fix tests due to Redis reply order changes in 2.6.5+ (Bryce Baril)
-* Added a test for the SLOWLOG command (Nitesh Sinha)
-* Fix SMEMBERS order dependency in test broken by Redis changes (Garrett Johnson)
-* Update commands for new Redis commands (David Trejo)
-* Prevent exception from SELECT on subscriber reconnection (roamm)
+- Fix some tests for Node.js version 0.9.x+ changes (Roman Ivanilov)
+- Fix error when commands submitted after idle event handler (roamm)
+- Bypass Redis for no-op SET/SETEX commands (jifeng)
+- Fix HMGET + detect_buffers (Joffrey F)
+- Fix CLIENT LOAD functionality (Jonas Dohse)
+- Add percentage outputs to diff_multi_bench_output.js (Bryce Baril)
+- Add retry_max_delay option (Tomasz Durka)
+- Fix parser off-by-one errors with nested multi-bulk replies (Bryce Baril)
+- Prevent parser from sinking application-side exceptions (Bryce Baril)
+- Fix parser incorrect buffer skip when parsing multi-bulk errors (Bryce Baril)
+- Reverted previous change with throwing on non-string values with HMSET (David Trejo)
+- Fix command queue sync issue when using pubsub (Tom Leach)
+- Fix compatibility with two-word Redis commands (Jonas Dohse)
+- Add EVAL with array syntax (dmoena)
+- Fix tests due to Redis reply order changes in 2.6.5+ (Bryce Baril)
+- Added a test for the SLOWLOG command (Nitesh Sinha)
+- Fix SMEMBERS order dependency in test broken by Redis changes (Garrett Johnson)
+- Update commands for new Redis commands (David Trejo)
+- Prevent exception from SELECT on subscriber reconnection (roamm)
## v0.8.2 - November 11, 2012
@@ -650,20 +655,20 @@ Important bug fix for null responses (Jerry Sievert)
Many contributed features and fixes, including:
-* Pure JavaScript reply parser that is usually faster than hiredis (Jerry Sievert)
-* Remove hiredis as optionalDependency from package.json. It still works if you want it.
-* Restore client state on reconnect, including select, subscribe, and monitor. (Ignacio Burgueño)
-* Fix idle event (Trae Robrock)
-* Many documentation improvements and bug fixes (David Trejo)
+- Pure JavaScript reply parser that is usually faster than hiredis (Jerry Sievert)
+- Remove hiredis as optionalDependency from package.json. It still works if you want it.
+- Restore client state on reconnect, including select, subscribe, and monitor. (Ignacio Burgueño)
+- Fix idle event (Trae Robrock)
+- Many documentation improvements and bug fixes (David Trejo)
## v0.7.2 - April 29, 2012
Many contributed fixes. Thank you, contributors.
-* [GH-190] - pub/sub mode fix (Brian Noguchi)
-* [GH-165] - parser selection fix (TEHEK)
-* numerous documentation and examples updates
-* auth errors emit Errors instead of Strings (David Trejo)
+- [GH-190] - pub/sub mode fix (Brian Noguchi)
+- [GH-165] - parser selection fix (TEHEK)
+- numerous documentation and examples updates
+- auth errors emit Errors instead of Strings (David Trejo)
## v0.7.1 - November 15, 2011
@@ -675,21 +680,21 @@ Very much need automated tests for reconnection and queue logic.
Many contributed fixes. Thanks everybody.
-* [GH-127] - properly re-initialize parser on reconnect
-* [GH-136] - handle passing undefined as callback (Ian Babrou)
-* [GH-139] - properly handle exceptions thrown in pub/sub event handlers (Felix Geisendörfer)
-* [GH-141] - detect closing state on stream error (Felix Geisendörfer)
-* [GH-142] - re-select database on reconnection (Jean-Hugues Pinson)
-* [GH-146] - add sort example (Maksim Lin)
+- [GH-127] - properly re-initialize parser on reconnect
+- [GH-136] - handle passing undefined as callback (Ian Babrou)
+- [GH-139] - properly handle exceptions thrown in pub/sub event handlers (Felix Geisendörfer)
+- [GH-141] - detect closing state on stream error (Felix Geisendörfer)
+- [GH-142] - re-select database on reconnection (Jean-Hugues Pinson)
+- [GH-146] - add sort example (Maksim Lin)
Some more goodies:
-* Fix bugs with node 0.6
-* Performance improvements
-* New version of `multi_bench.js` that tests more realistic scenarios
-* [GH-140] - support optional callback for subscribe commands
-* Properly flush and error out command queue when connection fails
-* Initial work on reconnection thresholds
+- Fix bugs with node 0.6
+- Performance improvements
+- New version of `multi_bench.js` that tests more realistic scenarios
+- [GH-140] - support optional callback for subscribe commands
+- Properly flush and error out command queue when connection fails
+- Initial work on reconnection thresholds
## v0.6.7 - July 30, 2011
@@ -698,16 +703,16 @@ Some more goodies:
Fix and test for [GH-123]
Passing an Array as as the last argument should expand as users
-expect. The old behavior was to coerce the arguments into Strings,
+expect. The old behavior was to coerce the arguments into Strings,
which did surprising things with Arrays.
## v0.6.5 - July 6, 2011
Contributed changes:
-* Support SlowBuffers (Umair Siddique)
-* Add Multi to exports (Louis-Philippe Perron)
-* Fix for drain event calculation (Vladimir Dronnikov)
+- Support SlowBuffers (Umair Siddique)
+- Add Multi to exports (Louis-Philippe Perron)
+- Fix for drain event calculation (Vladimir Dronnikov)
Thanks!
@@ -719,15 +724,15 @@ Fix bug with optional callbacks for hmset.
Bugs fixed:
-* authentication retry while server is loading db (danmaz74) [GH-101]
-* command arguments processing issue with arrays
+- authentication retry while server is loading db (danmaz74) [GH-101]
+- command arguments processing issue with arrays
New features:
-* Auto update of new commands from redis.io (Dave Hoover)
-* Performance improvements and backpressure controls.
-* Commands now return the true/false value from the underlying socket write(s).
-* Implement command_queue high water and low water for more better control of queueing.
+- Auto update of new commands from redis.io (Dave Hoover)
+- Performance improvements and backpressure controls.
+- Commands now return the true/false value from the underlying socket write(s).
+- Implement command_queue high water and low water for more better control of queueing.
See `examples/backpressure_drain.js` for more information.
@@ -735,7 +740,7 @@ See `examples/backpressure_drain.js` for more information.
Add support and tests for Redis scripting through EXEC command.
-Bug fix for monitor mode. (forddg)
+Bug fix for monitor mode. (forddg)
Auto update of new commands from redis.io (Dave Hoover)
@@ -743,12 +748,12 @@ Auto update of new commands from redis.io (Dave Hoover)
Lots of bugs fixed.
-* connection error did not properly trigger reconnection logic [GH-85]
-* client.hmget(key, [val1, val2]) was not expanding properly [GH-66]
-* client.quit() while in pub/sub mode would throw an error [GH-87]
-* client.multi(['hmset', 'key', {foo: 'bar'}]) fails [GH-92]
-* unsubscribe before subscribe would make things very confused [GH-88]
-* Add BRPOPLPUSH [GH-79]
+- connection error did not properly trigger reconnection logic [GH-85]
+- client.hmget(key, [val1, val2]) was not expanding properly [GH-66]
+- client.quit() while in pub/sub mode would throw an error [GH-87]
+- client.multi(['hmset', 'key', {foo: 'bar'}]) fails [GH-92]
+- unsubscribe before subscribe would make things very confused [GH-88]
+- Add BRPOPLPUSH [GH-79]
## v0.5.11 - April 7, 2011
@@ -788,17 +793,17 @@ Add probe for server readiness.
When a Redis server starts up, it might take a while to load the dataset into memory.
During this time, the server will accept connections, but will return errors for all non-INFO
-commands. Now node_redis will send an INFO command whenever it connects to a server.
+commands. Now node_redis will send an INFO command whenever it connects to a server.
If the info command indicates that the server is not ready, the client will keep trying until
-the server is ready. Once it is ready, the client will emit a "ready" event as well as the
-"connect" event. The client will queue up all commands sent before the server is ready, just
-like it did before. When the server is ready, all offline/non-ready commands will be replayed.
+the server is ready. Once it is ready, the client will emit a "ready" event as well as the
+"connect" event. The client will queue up all commands sent before the server is ready, just
+like it did before. When the server is ready, all offline/non-ready commands will be replayed.
This should be backward compatible with previous versions.
To disable this ready check behavior, set `options.no_ready_check` when creating the client.
As a side effect of this change, the key/val params from the info command are available as
-`client.server_options`. Further, the version string is decomposed into individual elements
+`client.server_options`. Further, the version string is decomposed into individual elements
in `client.server_options.versions`.
## v0.5.4 - February 11, 2011
@@ -825,17 +830,17 @@ Fix bug where subscribe commands would not handle redis-server startup error pro
Some bug fixes:
-* An important bug fix in reconnection logic. Previously, reply callbacks would be invoked twice after
+- An important bug fix in reconnection logic. Previously, reply callbacks would be invoked twice after
a reconnect.
-* Changed error callback argument to be an actual Error object.
+- Changed error callback argument to be an actual Error object.
New feature:
-* Add friendly syntax for HMSET using an object.
+- Add friendly syntax for HMSET using an object.
## v0.4.1 - December 8, 2010
-Remove warning about missing hiredis. You probably do want it though.
+Remove warning about missing hiredis. You probably do want it though.
## v0.4.0 - December 5, 2010
@@ -865,9 +870,9 @@ Send a friendlier "error" event message on stream errors like connection refused
A few bug fixes.
-* Fixed bug with `nil` multi-bulk reply lengths that showed up with `BLPOP` timeouts.
-* Only emit `end` once when connection goes away.
-* Fixed bug in `test.js` where driver finished before all tests completed.
+- Fixed bug with `nil` multi-bulk reply lengths that showed up with `BLPOP` timeouts.
+- Only emit `end` once when connection goes away.
+- Fixed bug in `test.js` where driver finished before all tests completed.
## unversioned wasteland
diff --git a/README.md b/README.md
index bd124739b2..49a21019ed 100644
--- a/README.md
+++ b/README.md
@@ -19,115 +19,43 @@
---
-This is a complete and feature rich Redis client for Node.js. **It supports all
-Redis commands** and focuses on high performance.
-
-Install with:
+## Installation
```bash
npm install redis
```
-## Usage Example
+## Usage
+
+#### Example
```js
-const redis = require('redis');
+const redis = require("redis");
const client = redis.createClient();
-// if you'd like to select database 3, instead of 0 (default), call
-// client.select(3, function() { /* ... */ });
-
-client.on('error', function(err) {
- console.log('Error ' + err);
+client.on("error", function(err) {
+ console.log("Error " + err);
});
-client.set('string key', 'string val', redis.print);
-client.hset('hash key', 'hashtest 1', 'some value', redis.print);
-client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print);
-client.hkeys('hash key', function(err, replies) {
- console.log(replies.length + ' replies:');
- replies.forEach(function(reply, i) {
- console.log(' ' + i + ': ' + reply);
- });
- client.quit();
-});
+client.set("string key", "string val", redis.print);
+client.get("string key", redis.print);
```
-This will display:
-
- mjr:~/work/node_redis (master)$ node example.js
- Reply: OK
- Reply: 0
- Reply: 0
- 2 replies:
- 0: hashtest 1
- 1: hashtest 2
- mjr:~/work/node_redis (master)$
-
Note that the API is entirely asynchronous. To get data back from the server,
-you'll need to use a callback. From v.2.6 on the API supports camelCase and
-snake_case and all options / variables / events etc. can be used either way. It
-is recommended to use camelCase as this is the default for the Node.js
-landscape.
+you'll need to use a callback.
### Promises
-#### Native Promises
-
-If you are using node v8 or higher, you can promisify node_redis with [util.promisify](https://nodejs.org/api/util.html#util_util_promisify_original) as in:
+Node Redis currently doesn't natively support promises (this is coming in v4), however you can wrap the methods you
+want to use with promises using the built-in Node.js `util.promisify` method on Node.js >= v8;
```js
-const { promisify } = require('util');
+const { promisify } = require("util");
const getAsync = promisify(client.get).bind(client);
-```
-now _getAsync_ is a promisified version of _client.get_:
-
-```js
-// We expect a value 'foo': 'bar' to be present
-// So instead of writing client.get('foo', cb); you have to write:
-return getAsync('foo').then(function(res) {
- console.log(res); // => 'bar'
-});
-```
-
-or using [async await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function):
-
-```js
-async function myFunc() {
- const res = await getAsync('foo');
- console.log(res);
-}
-```
-
-#### Bluebird Promises
-
-You can also use node_redis with promises by promisifying node_redis with
-[bluebird](https://github.com/petkaantonov/bluebird) as in:
-
-```js
-const redis = require('redis');
-bluebird.promisifyAll(redis);
-```
-
-It'll add a _Async_ to all node_redis functions (e.g. return client.getAsync().then())
-
-```js
-// We expect a value 'foo': 'bar' to be present
-// So instead of writing client.get('foo', cb); you have to write:
-return client.getAsync('foo').then(function(res) {
- console.log(res); // => 'bar'
-});
-
-// Using multi with promises looks like:
-
-return client
- .multi()
- .get('foo')
- .execAsync()
- .then(function(res) {
- console.log(res); // => 'bar'
- });
+getAsync
+ .then(console.log)
+ .catch(console.error);
```
### Sending Commands
@@ -138,16 +66,15 @@ a variable number of individual arguments followed by an optional callback.
Examples:
```js
-client.hmset(['key', 'test keys 1', 'test val 1', 'test keys 2', 'test val 2'], function(
- err,
- res,
-) {});
+client.hmset(["key", "test keys 1", "test val 1", "test keys 2", "test val 2"], function(err, res) {
+ // ...
+});
// Works the same as
-client.hmset('key', ['test keys 1', 'test val 1', 'test keys 2', 'test val 2'], function(err, res) {
+client.hmset("key", ["test keys 1", "test val 1", "test keys 2", "test val 2"], function(err, res) {
// ...
});
// Or
-client.hmset('key', 'test keys 1', 'test val 1', 'test keys 2', 'test val 2', function(err, res) {
+client.hmset("key", "test keys 1", "test val 1", "test keys 2", "test val 2", function(err, res) {
// ...
});
```
@@ -157,15 +84,15 @@ Care should be taken with user input if arrays are possible (via body-parser, qu
Note that in either form the `callback` is optional:
```js
-client.set('some key', 'some val');
-client.set(['some other key', 'some val']);
+client.set("some key", "some val");
+client.set(["some other key", "some val"]);
```
If the key is missing, reply will be null. Only if the [Redis Command
Reference](http://redis.io/commands) states something else it will not be null.
```js
-client.get('missingkey', function(err, reply) {
+client.get("missingkey", function(err, reply) {
// reply is null when the key is missing
console.log(reply);
});
@@ -189,7 +116,7 @@ Example setting key to auto expire using [SET command](https://redis.io/commands
```js
// this key will expire after 10 seconds
-client.set('key', 'value!', 'EX', 10);
+client.set("key", "value!", "EX", 10);
```
# API
@@ -275,18 +202,18 @@ using unix sockets if possible to increase throughput.
| retry_strategy | function | A function that receives an options object as parameter including the retry `attempt`, the `total_retry_time` indicating how much time passed since the last time connected, the `error` why the connection was lost and the number of `times_connected` in total. If you return a number from this function, the retry will happen exactly after that time in milliseconds. If you return a non-number, no further retry will happen and all offline commands are flushed with errors. Return an error to return that specific error to all offline commands. Example below. |
```js
-var redis = require('redis');
+var redis = require("redis");
var client = redis.createClient({ detect_buffers: true });
-client.set('foo_rand000000000000', 'OK');
+client.set("foo_rand000000000000", "OK");
// This will return a JavaScript String
-client.get('foo_rand000000000000', function(err, reply) {
+client.get("foo_rand000000000000", function(err, reply) {
console.log(reply.toString()); // Will print `OK`
});
// This will return a Buffer since original key is specified as a Buffer
-client.get(new Buffer('foo_rand000000000000'), function(err, reply) {
+client.get(new Buffer("foo_rand000000000000"), function(err, reply) {
console.log(reply.toString()); // Will print ``
});
client.quit();
@@ -297,15 +224,15 @@ client.quit();
```js
var client = redis.createClient({
retry_strategy: function(options) {
- if (options.error && options.error.code === 'ECONNREFUSED') {
+ if (options.error && options.error.code === "ECONNREFUSED") {
// End reconnecting on a specific error and flush all commands with
// a individual error
- return new Error('The server refused the connection');
+ return new Error("The server refused the connection");
}
if (options.total_retry_time > 1000 * 60 * 60) {
// End reconnecting after a specific timeout and flush all commands
// with a individual error
- return new Error('Retry time exhausted');
+ return new Error("Retry time exhausted");
}
if (options.attempt > 10) {
// End reconnecting with built in error
@@ -363,23 +290,23 @@ This example closes the connection to the Redis server before the replies have
been read. You probably don't want to do this:
```js
-var redis = require('redis'),
+var redis = require("redis"),
client = redis.createClient();
-client.set('foo_rand000000000000', 'some fantastic value', function(err, reply) {
+client.set("foo_rand000000000000", "some fantastic value", function(err, reply) {
// This will either result in an error (flush parameter is set to true)
// or will silently fail and this callback will not be called at all (flush set to false)
console.log(err);
});
client.end(true); // No further commands will be processed
-client.get('foo_rand000000000000', function(err, reply) {
+client.get("foo_rand000000000000", function(err, reply) {
console.log(err); // => 'The connection has already been closed.'
});
```
`client.end()` without the flush parameter set to true should NOT be used in production!
-## Error handling (>= v.2.6)
+## Error handling (>= v2.6)
Currently the following error subclasses exist:
@@ -398,27 +325,27 @@ All error classes are exported by the module.
Example:
```js
-var redis = require('./');
-var assert = require('assert');
+var redis = require("./");
+var assert = require("assert");
var client = redis.createClient();
-client.on('error', function(err) {
+client.on("error", function(err) {
assert(err instanceof Error);
assert(err instanceof redis.AbortError);
assert(err instanceof redis.AggregateError);
// The set and get get aggregated in here
assert.strictEqual(err.errors.length, 2);
- assert.strictEqual(err.code, 'NR_CLOSED');
+ assert.strictEqual(err.code, "NR_CLOSED");
});
-client.set('foo', 123, 'bar', function(err, res) {
+client.set("foo", 123, "bar", function(err, res) {
// Too many arguments
assert(err instanceof redis.ReplyError); // => true
- assert.strictEqual(err.command, 'SET');
- assert.deepStrictEqual(err.args, ['foo', 123, 'bar']);
+ assert.strictEqual(err.command, "SET");
+ assert.deepStrictEqual(err.args, ["foo", 123, "bar"]);
redis.debug_mode = true;
- client.set('foo', 'bar');
- client.get('foo');
+ client.set("foo", "bar");
+ client.get("foo");
process.nextTick(function() {
// Force closing the connection while the command did not yet return
client.end(true);
@@ -449,7 +376,7 @@ protocol. Any commands where client state is saved on the Redis server, e.g.
`*SUBSCRIBE` or the blocking `BL*` commands will _NOT_ work with `.unref()`.
```js
-var redis = require('redis');
+var redis = require("redis");
var client = redis.createClient();
/*
@@ -458,7 +385,7 @@ var client = redis.createClient();
client-server connection is alive.
*/
client.unref();
-client.get('foo', function(err, value) {
+client.get("foo", function(err, value) {
if (err) throw err;
console.log(value);
});
@@ -479,8 +406,8 @@ syntax.
Example:
```js
-client.hmset('hosts', 'mjr', '1', 'another', '23', 'home', '1234');
-client.hgetall('hosts', function(err, obj) {
+client.hmset("hosts", "mjr", "1", "another", "23", "home", "1234");
+client.hgetall("hosts", function(err, obj) {
console.dir(obj);
});
```
@@ -491,8 +418,8 @@ Multiple values in a hash can be set by supplying an object:
```js
client.HMSET(key2, {
- '0123456789': 'abcdefghij', // NOTE: key and value will be coerced to strings
- 'some manner of key': 'a type of value',
+ "0123456789": "abcdefghij", // NOTE: key and value will be coerced to strings
+ "some manner of key": "a type of value",
});
```
@@ -504,7 +431,7 @@ Redis hash.
Multiple values may also be set by supplying a list:
```js
-client.HMSET(key1, '0123456789', 'abcdefghij', 'some manner of key', 'a type of value');
+client.HMSET(key1, "0123456789", "abcdefghij", "some manner of key", "a type of value");
```
## Publish / Subscribe
@@ -514,19 +441,19 @@ client connections, subscribes to a channel on one of them, and publishes to tha
channel on the other:
```js
-var redis = require('redis');
+var redis = require("redis");
var sub = redis.createClient(),
pub = redis.createClient();
var msg_count = 0;
-sub.on('subscribe', function(channel, count) {
- pub.publish('a nice channel', 'I am sending a message.');
- pub.publish('a nice channel', 'I am sending a second message.');
- pub.publish('a nice channel', 'I am sending my last message.');
+sub.on("subscribe", function(channel, count) {
+ pub.publish("a nice channel", "I am sending a message.");
+ pub.publish("a nice channel", "I am sending a second message.");
+ pub.publish("a nice channel", "I am sending my last message.");
});
-sub.on('message', function(channel, message) {
- console.log('sub channel ' + channel + ': ' + message);
+sub.on("message", function(channel, message) {
+ console.log("sub channel " + channel + ": " + message);
msg_count += 1;
if (msg_count === 3) {
sub.unsubscribe();
@@ -535,7 +462,7 @@ sub.on('message', function(channel, message) {
}
});
-sub.subscribe('a nice channel');
+sub.subscribe("a nice channel");
```
When a client issues a `SUBSCRIBE` or `PSUBSCRIBE`, that connection is put into
@@ -610,33 +537,33 @@ further information look at
[transactions](http://redis.io/topics/transactions)).
```js
-var redis = require('./index'),
+var redis = require("./index"),
client = redis.createClient(),
set_size = 20;
-client.sadd('bigset', 'a member');
-client.sadd('bigset', 'another member');
+client.sadd("bigset", "a member");
+client.sadd("bigset", "another member");
while (set_size > 0) {
- client.sadd('bigset', 'member ' + set_size);
+ client.sadd("bigset", "member " + set_size);
set_size -= 1;
}
// multi chain with an individual callback
client
.multi()
- .scard('bigset')
- .smembers('bigset')
- .keys('*', function(err, replies) {
+ .scard("bigset")
+ .smembers("bigset")
+ .keys("*", function(err, replies) {
// NOTE: code in this callback is NOT atomic
// this only happens after the the .exec call finishes.
client.mget(replies, redis.print);
})
.dbsize()
.exec(function(err, replies) {
- console.log('MULTI got ' + replies.length + ' replies');
+ console.log("MULTI got " + replies.length + " replies");
replies.forEach(function(reply, index) {
- console.log('Reply ' + index + ': ' + reply.toString());
+ console.log("Reply " + index + ": " + reply.toString());
});
});
```
@@ -659,17 +586,17 @@ can queue individual commands while still sending regular client command as in
this example:
```js
-var redis = require('redis'),
+var redis = require("redis"),
client = redis.createClient(),
multi;
// start a separate multi command queue
multi = client.multi();
-multi.incr('incr thing', redis.print);
-multi.incr('incr other thing', redis.print);
+multi.incr("incr thing", redis.print);
+multi.incr("incr other thing", redis.print);
// runs immediately
-client.mset('incr thing', 100, 'incr other thing', 1, redis.print);
+client.mset("incr thing", 100, "incr other thing", 1, redis.print);
// drains multi queue and runs atomically
multi.exec(function(err, replies) {
@@ -681,14 +608,14 @@ In addition to adding commands to the `MULTI` queue individually, you can also
pass an array of commands and arguments to the constructor:
```js
-var redis = require('redis'),
+var redis = require("redis"),
client = redis.createClient();
client
.multi([
- ['mget', 'multifoo', 'multibar', redis.print],
- ['incr', 'multifoo'],
- ['incr', 'multibar'],
+ ["mget", "multifoo", "multibar", redis.print],
+ ["incr", "multifoo"],
+ ["incr", "multibar"],
])
.exec(function(err, replies) {
console.log(replies);
@@ -853,14 +780,14 @@ arguments and the raw monitoring string.
Example:
```js
-var client = require('redis').createClient();
+var client = require("redis").createClient();
client.monitor(function(err, res) {
- console.log('Entering monitoring mode.');
+ console.log("Entering monitoring mode.");
});
-client.set('foo', 'bar');
+client.set("foo", "bar");
-client.on('monitor', function(time, args, raw_reply) {
- console.log(time + ': ' + args); // 1458910076.446514:['set', 'foo', 'bar']
+client.on("monitor", function(time, args, raw_reply) {
+ console.log(time + ": " + args); // 1458910076.446514:['set', 'foo', 'bar']
});
```
@@ -886,12 +813,12 @@ easy comparison.
A handy callback function for displaying return values when testing. Example:
```js
-var redis = require('redis'),
+var redis = require("redis"),
client = redis.createClient();
-client.on('connect', function() {
- client.set('foo_rand000000000000', 'some fantastic value', redis.print);
- client.get('foo_rand000000000000', redis.print);
+client.on("connect", function() {
+ client.set("foo_rand000000000000", "some fantastic value", redis.print);
+ client.get("foo_rand000000000000", redis.print);
});
```
@@ -908,12 +835,12 @@ To execute redis multi-word commands like `SCRIPT LOAD` or `CLIENT LIST` pass
the second word as first parameter:
```js
-client.script('load', 'return 1');
+client.script("load", "return 1");
client
.multi()
- .script('load', 'return 1')
+ .script("load", "return 1")
.exec();
-client.multi([['script', 'load', 'return 1']]).exec();
+client.multi([["script", "load", "return 1"]]).exec();
```
## client.duplicate([options][, callback])
@@ -930,21 +857,21 @@ are used on the same redisClient instance as non-blocking commands, the
non-blocking ones may be queued up until after the blocking ones finish.
```js
-var Redis = require('redis');
+var Redis = require("redis");
var client = Redis.createClient();
var clientBlocking = client.duplicate();
var get = function() {
- console.log('get called');
- client.get('any_key', function() {
- console.log('get returned');
+ console.log("get called");
+ client.get("any_key", function() {
+ console.log("get returned");
});
setTimeout(get, 1000);
};
var brpop = function() {
- console.log('brpop called');
- clientBlocking.brpop('nonexistent', 5, function() {
- console.log('brpop return');
+ console.log("brpop called");
+ clientBlocking.brpop("nonexistent", 5, function() {
+ console.log("brpop return");
setTimeout(brpop, 1000);
});
};
@@ -994,16 +921,16 @@ This applies to anything that uses an optional `[WITHSCORES]` or `[LIMIT offset
Example:
```js
-var args = ['myzset', 1, 'one', 2, 'two', 3, 'three', 99, 'ninety-nine'];
+var args = ["myzset", 1, "one", 2, "two", 3, "three", 99, "ninety-nine"];
client.zadd(args, function(err, response) {
if (err) throw err;
- console.log('added ' + response + ' items.');
+ console.log("added " + response + " items.");
// -Infinity and +Infinity also work
- var args1 = ['myzset', '+inf', '-inf'];
+ var args1 = ["myzset", "+inf", "-inf"];
client.zrevrangebyscore(args1, function(err, response) {
if (err) throw err;
- console.log('example1', response);
+ console.log("example1", response);
// write your code here
});
@@ -1011,10 +938,10 @@ client.zadd(args, function(err, response) {
min = 1,
offset = 1,
count = 2;
- var args2 = ['myzset', max, min, 'WITHSCORES', 'LIMIT', offset, count];
+ var args2 = ["myzset", max, min, "WITHSCORES", "LIMIT", offset, count];
client.zrevrangebyscore(args2, function(err, response) {
if (err) throw err;
- console.log('example2', response);
+ console.log("example2", response);
// write your code here
});
});
From 41c8177e8def055042cedc13dca90bb0b5887523 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 02:43:10 +0000
Subject: [PATCH 63/96] docs
---
README.md | 152 +++++++++++++++++++++++++-----------------------------
1 file changed, 70 insertions(+), 82 deletions(-)
diff --git a/README.md b/README.md
index 49a21019ed..935338cdbd 100644
--- a/README.md
+++ b/README.md
@@ -47,18 +47,18 @@ you'll need to use a callback.
### Promises
Node Redis currently doesn't natively support promises (this is coming in v4), however you can wrap the methods you
-want to use with promises using the built-in Node.js `util.promisify` method on Node.js >= v8;
+want to use with promises using the built-in Node.js `util.promisify` method on Node.js >= v8;
```js
const { promisify } = require("util");
const getAsync = promisify(client.get).bind(client);
-getAsync
- .then(console.log)
- .catch(console.error);
+getAsync.then(console.log).catch(console.error);
```
-### Sending Commands
+### Commands
+
+This library is a 1 to 1 mapping of the [Redis commands](https://redis.io/commands).
Each Redis command is exposed as a function on the `client` object.
All functions take either an `args` Array plus optional `callback` Function or
@@ -98,50 +98,35 @@ client.get("missingkey", function(err, reply) {
});
```
-For a list of Redis commands, see [Redis Command Reference](http://redis.io/commands)
-
Minimal parsing is done on the replies. Commands that return a integer return
JavaScript Numbers, arrays return JavaScript Array. `HGETALL` returns an Object
keyed by the hash keys. All strings will either be returned as string or as
buffer depending on your setting. Please be aware that sending null, undefined
and Boolean values will result in the value coerced to a string!
-# Redis Commands
+## API
-This library is a 1 to 1 mapping to [Redis commands](https://redis.io/commands).
-It is not a cache library so please refer to Redis commands page for full usage
-details.
-
-Example setting key to auto expire using [SET command](https://redis.io/commands/set)
-
-```js
-// this key will expire after 10 seconds
-client.set("key", "value!", "EX", 10);
-```
-
-# API
-
-## Connection and other Events
+### Connection and other Events
`client` will emit some events about the state of the connection to the Redis server.
-### "ready"
+#### "ready"
`client` will emit `ready` once a connection is established. Commands issued
before the `ready` event are queued, then replayed just before this event is
emitted.
-### "connect"
+#### "connect"
`client` will emit `connect` as soon as the stream is connected to the server.
-### "reconnecting"
+#### "reconnecting"
`client` will emit `reconnecting` when trying to reconnect to the Redis server
after losing the connection. Listeners are passed an object containing `delay`
(in ms from the previous try) and `attempt` (the attempt #) attributes.
-### "error"
+#### "error"
`client` will emit `error` when encountering an error connecting to the Redis
server or when any other in node_redis occurs. If you use a command without
@@ -150,16 +135,16 @@ listener.
So please attach the error listener to node_redis.
-### "end"
+#### "end"
`client` will emit `end` when an established Redis server connection has closed.
-### "warning"
+#### "warning"
`client` will emit `warning` when password was set but none is needed and if a
deprecated option / function / similar is used.
-## redis.createClient()
+### redis.createClient()
If you have `redis-server` running on the same machine as node, then the
defaults for port and host are probably fine and you don't need to supply any
@@ -201,9 +186,11 @@ using unix sockets if possible to increase throughput.
| prefix | null | A string used to prefix all used keys (e.g. `namespace:test`). Please be aware that the `keys` command will not be prefixed. The `keys` command has a "pattern" as argument and no key and it would be impossible to determine the existing keys in Redis if this would be prefixed. |
| retry_strategy | function | A function that receives an options object as parameter including the retry `attempt`, the `total_retry_time` indicating how much time passed since the last time connected, the `error` why the connection was lost and the number of `times_connected` in total. If you return a number from this function, the retry will happen exactly after that time in milliseconds. If you return a non-number, no further retry will happen and all offline commands are flushed with errors. Return an error to return that specific error to all offline commands. Example below. |
+**`detect_buffers` example:**
+
```js
-var redis = require("redis");
-var client = redis.createClient({ detect_buffers: true });
+const redis = require("redis");
+const client = redis.createClient({ detect_buffers: true });
client.set("foo_rand000000000000", "OK");
@@ -216,10 +203,9 @@ client.get("foo_rand000000000000", function(err, reply) {
client.get(new Buffer("foo_rand000000000000"), function(err, reply) {
console.log(reply.toString()); // Will print ``
});
-client.quit();
```
-#### `retry_strategy` example
+**`retry_strategy` example:**
```js
var client = redis.createClient({
@@ -244,7 +230,7 @@ var client = redis.createClient({
});
```
-## client.auth(password[, callback])
+### client.auth(password[, callback])
When connecting to a Redis server that requires authentication, the `AUTH`
command must be sent as the first command after connecting. This can be tricky
@@ -256,19 +242,7 @@ NOTE: Your call to `client.auth()` should not be inside the ready handler. If
you are doing this wrong, `client` will emit an error that looks
something like this `Error: Ready check failed: ERR operation not permitted`.
-## backpressure
-
-### stream
-
-The client exposed the used [stream](https://nodejs.org/api/stream.html) in
-`client.stream` and if the stream or client had to
-[buffer](https://nodejs.org/api/stream.html#stream_writable_write_chunk_encoding_callback)
-the command in `client.should_buffer`. In combination this can be used to
-implement backpressure by checking the buffer state before sending a command and
-listening to the stream
-[drain](https://nodejs.org/api/stream.html#stream_event_drain) event.
-
-## client.quit(callback)
+### client.quit(callback)
This sends the quit command to the redis server and ends cleanly right after all
running commands were properly handled. If this is called while reconnecting
@@ -276,7 +250,7 @@ running commands were properly handled. If this is called while reconnecting
connection right away instead of resulting in further reconnections! All offline
commands are going to be flushed with an error in that case.
-## client.end(flush)
+### client.end(flush)
Forcibly close the connection to the Redis server. Note that this does not wait
until all replies have been parsed. If you want to exit cleanly, call
@@ -290,25 +264,28 @@ This example closes the connection to the Redis server before the replies have
been read. You probably don't want to do this:
```js
-var redis = require("redis"),
- client = redis.createClient();
+const redis = require("redis");
+const client = redis.createClient();
-client.set("foo_rand000000000000", "some fantastic value", function(err, reply) {
+client.set("hello", "world", function(err) {
// This will either result in an error (flush parameter is set to true)
// or will silently fail and this callback will not be called at all (flush set to false)
- console.log(err);
+ console.error(err);
});
-client.end(true); // No further commands will be processed
-client.get("foo_rand000000000000", function(err, reply) {
- console.log(err); // => 'The connection has already been closed.'
+
+// No further commands will be processed
+client.end(true);
+
+client.get("hello", function(err) {
+ console.error(err); // => 'The connection has already been closed.'
});
```
`client.end()` without the flush parameter set to true should NOT be used in production!
-## Error handling (>= v2.6)
+### Error Handling
-Currently the following error subclasses exist:
+Currently the following `Error` subclasses exist:
- `RedisError`: _All errors_ returned by the client
- `ReplyError` subclass of `RedisError`: All errors returned by **Redis** itself
@@ -322,30 +299,36 @@ Currently the following error subclasses exist:
All error classes are exported by the module.
-Example:
+#### Example
```js
-var redis = require("./");
-var assert = require("assert");
-var client = redis.createClient();
+const assert = require("assert");
+
+const redis = require("redis");
+const { AbortError, AggregateError, ReplyError } = require("redis");
+const client = redis.createClient();
client.on("error", function(err) {
assert(err instanceof Error);
- assert(err instanceof redis.AbortError);
- assert(err instanceof redis.AggregateError);
- // The set and get get aggregated in here
+ assert(err instanceof AbortError);
+ assert(err instanceof AggregateError);
+
+ // The set and get are aggregated in here
assert.strictEqual(err.errors.length, 2);
assert.strictEqual(err.code, "NR_CLOSED");
});
-client.set("foo", 123, "bar", function(err, res) {
+
+client.set("foo", "bar", "baz", function(err, res) {
// Too many arguments
- assert(err instanceof redis.ReplyError); // => true
+ assert(err instanceof ReplyError); // => true
assert.strictEqual(err.command, "SET");
assert.deepStrictEqual(err.args, ["foo", 123, "bar"]);
redis.debug_mode = true;
+
client.set("foo", "bar");
client.get("foo");
+
process.nextTick(function() {
// Force closing the connection while the command did not yet return
client.end(true);
@@ -366,7 +349,7 @@ If a command unresolved command got rejected a `UNCERTAIN_STATE` code is
returned. A `CONNECTION_BROKEN` error code is used in case node_redis gives up
to reconnect.
-## client.unref()
+### client.unref()
Call `unref()` on the underlying socket connection to the Redis server, allowing
the program to exit once no more commands are pending.
@@ -376,34 +359,35 @@ protocol. Any commands where client state is saved on the Redis server, e.g.
`*SUBSCRIBE` or the blocking `BL*` commands will _NOT_ work with `.unref()`.
```js
-var redis = require("redis");
-var client = redis.createClient();
+const redis = require("redis");
+const client = redis.createClient();
/*
- Calling unref() will allow this program to exit immediately after the get
- command finishes. Otherwise the client would hang as long as the
- client-server connection is alive.
-*/
+ * Calling unref() will allow this program to exit immediately after the get
+ * command finishes. Otherwise the client would hang as long as the
+ * client-server connection is alive.
+ */
client.unref();
+
client.get("foo", function(err, value) {
if (err) throw err;
console.log(value);
});
```
-## Friendlier hash commands
+### Hash Commands
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. When
dealing with hash values, there are a couple of useful exceptions to this.
-### client.hgetall(hash, callback)
+#### client.hgetall(hash, callback)
-The reply from an HGETALL command will be converted into a JavaScript Object by
+The reply from an `HGETALL` command will be converted into a JavaScript Object by
`node_redis`. That way you can interact with the responses using JavaScript
syntax.
-Example:
+**Example:**
```js
client.hmset("hosts", "mjr", "1", "another", "23", "home", "1234");
@@ -412,9 +396,11 @@ client.hgetall("hosts", function(err, obj) {
});
```
-### client.hmset(hash, obj[, callback])
+#### client.hmset(hash, obj[, callback])
-Multiple values in a hash can be set by supplying an object:
+Multiple values in a hash can be set by supplying an object.
+
+**Example:**
```js
client.HMSET(key2, {
@@ -426,15 +412,17 @@ client.HMSET(key2, {
The properties and values of this Object will be set as keys and values in the
Redis hash.
-### client.hmset(hash, key1, val1, ... keyn, valn, [callback])
+#### client.hmset(hash, key1, val1, ...keyN, valN, [callback])
-Multiple values may also be set by supplying a list:
+Multiple values may also be set by supplying more arguments.
+
+**Example:**
```js
client.HMSET(key1, "0123456789", "abcdefghij", "some manner of key", "a type of value");
```
-## Publish / Subscribe
+### Publish / Subscribe
Example of the publish / subscribe API. This program opens two
client connections, subscribes to a channel on one of them, and publishes to that
From 6803cf4e8fb3649b1a3d07763a33a41952febcac Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 03:07:01 +0000
Subject: [PATCH 64/96] docs
---
README.md | 171 ++++++++++++++++++++++++++----------------------------
1 file changed, 81 insertions(+), 90 deletions(-)
diff --git a/README.md b/README.md
index 935338cdbd..94b70f8396 100644
--- a/README.md
+++ b/README.md
@@ -33,12 +33,12 @@ npm install redis
const redis = require("redis");
const client = redis.createClient();
-client.on("error", function(err) {
- console.log("Error " + err);
+client.on("error", function(error) {
+ console.error(error);
});
-client.set("string key", "string val", redis.print);
-client.get("string key", redis.print);
+client.set("key", "value", redis.print);
+client.get("key", redis.print);
```
Note that the API is entirely asynchronous. To get data back from the server,
@@ -66,15 +66,17 @@ a variable number of individual arguments followed by an optional callback.
Examples:
```js
-client.hmset(["key", "test keys 1", "test val 1", "test keys 2", "test val 2"], function(err, res) {
+client.hmset(["key", "foo", "bar"], function(err, res) {
// ...
});
+
// Works the same as
-client.hmset("key", ["test keys 1", "test val 1", "test keys 2", "test val 2"], function(err, res) {
+client.hmset("key", ["foo", "bar"], function(err, res) {
// ...
});
+
// Or
-client.hmset("key", "test keys 1", "test val 1", "test keys 2", "test val 2", function(err, res) {
+client.hmset("key", "foo", "bar", function(err, res) {
// ...
});
```
@@ -84,15 +86,15 @@ Care should be taken with user input if arrays are possible (via body-parser, qu
Note that in either form the `callback` is optional:
```js
-client.set("some key", "some val");
-client.set(["some other key", "some val"]);
+client.set("foo", "bar");
+client.set(["hello", "world"]);
```
If the key is missing, reply will be null. Only if the [Redis Command
Reference](http://redis.io/commands) states something else it will not be null.
```js
-client.get("missingkey", function(err, reply) {
+client.get("missing_key", function(err, reply) {
// reply is null when the key is missing
console.log(reply);
});
@@ -110,23 +112,23 @@ and Boolean values will result in the value coerced to a string!
`client` will emit some events about the state of the connection to the Redis server.
-#### "ready"
+#### `"ready"`
`client` will emit `ready` once a connection is established. Commands issued
before the `ready` event are queued, then replayed just before this event is
emitted.
-#### "connect"
+#### `"connect"`
`client` will emit `connect` as soon as the stream is connected to the server.
-#### "reconnecting"
+#### `"reconnecting"`
`client` will emit `reconnecting` when trying to reconnect to the Redis server
after losing the connection. Listeners are passed an object containing `delay`
(in ms from the previous try) and `attempt` (the attempt #) attributes.
-#### "error"
+#### `"error"`
`client` will emit `error` when encountering an error connecting to the Redis
server or when any other in node_redis occurs. If you use a command without
@@ -135,11 +137,11 @@ listener.
So please attach the error listener to node_redis.
-#### "end"
+#### `"end"`
`client` will emit `end` when an established Redis server connection has closed.
-#### "warning"
+#### `"warning"`
`client` will emit `warning` when password was set but none is needed and if a
deprecated option / function / similar is used.
@@ -390,28 +392,14 @@ syntax.
**Example:**
```js
-client.hmset("hosts", "mjr", "1", "another", "23", "home", "1234");
-client.hgetall("hosts", function(err, obj) {
- console.dir(obj);
+client.hmset("key", "foo", "bar", "hello", "world");
+
+client.hgetall("hosts", function(err, value) {
+ console.log(value.foo); // > "bar"
+ console.log(value.hello); // > "world"
});
```
-#### client.hmset(hash, obj[, callback])
-
-Multiple values in a hash can be set by supplying an object.
-
-**Example:**
-
-```js
-client.HMSET(key2, {
- "0123456789": "abcdefghij", // NOTE: key and value will be coerced to strings
- "some manner of key": "a type of value",
-});
-```
-
-The properties and values of this Object will be set as keys and values in the
-Redis hash.
-
#### client.hmset(hash, key1, val1, ...keyN, valN, [callback])
Multiple values may also be set by supplying more arguments.
@@ -419,155 +407,158 @@ Multiple values may also be set by supplying more arguments.
**Example:**
```js
-client.HMSET(key1, "0123456789", "abcdefghij", "some manner of key", "a type of value");
+// key
+// 1) foo => bar
+// 2) hello => world
+client.HMSET("key", "foo", "bar", "hello", "world");
```
-### Publish / Subscribe
+### PubSub
-Example of the publish / subscribe API. This program opens two
-client connections, subscribes to a channel on one of them, and publishes to that
-channel on the other:
+#### Example
+
+This example opens two client connections, subscribes to a channel on one of them, and publishes to that
+channel on the other.
```js
-var redis = require("redis");
-var sub = redis.createClient(),
- pub = redis.createClient();
-var msg_count = 0;
+const redis = require("redis");
-sub.on("subscribe", function(channel, count) {
- pub.publish("a nice channel", "I am sending a message.");
- pub.publish("a nice channel", "I am sending a second message.");
- pub.publish("a nice channel", "I am sending my last message.");
+const subscriber = redis.createClient();
+const publisher = redis.createClient();
+
+let messageCount = 0;
+
+subscriber.on("subscribe", function(channel, count) {
+ publisher.publish("a channel", "a message");
+ publisher.publish("a channel", "another message");
});
-sub.on("message", function(channel, message) {
- console.log("sub channel " + channel + ": " + message);
- msg_count += 1;
- if (msg_count === 3) {
- sub.unsubscribe();
- sub.quit();
- pub.quit();
+subscriber.on("message", function(channel, message) {
+ messageCount += 1;
+
+ console.log("Subscriber received message in channel '" + channel + "': " + message);
+
+ if (messageCount === 2) {
+ subscriber.unsubscribe();
+ subscriber.quit();
+ publisher.quit();
}
});
-sub.subscribe("a nice channel");
+subscriber.subscribe("a channel");
```
When a client issues a `SUBSCRIBE` or `PSUBSCRIBE`, that connection is put into
-a "subscriber" mode. At that point, the only valid commands are those that modify the subscription
+a `"subscriber"` mode. At that point, the only valid commands are those that modify the subscription
set, and quit (also ping on some redis versions). When
the subscription set is empty, the connection is put back into regular mode.
If you need to send regular commands to Redis while in subscriber mode, just
-open another connection with a new client (hint: use `client.duplicate()`).
+open another connection with a new client (use `client.duplicate()` to quickly duplicate an existing client).
-## Subscriber Events
+#### Subscriber Events
If a client has subscriptions active, it may emit these events:
-### "message" (channel, message)
+**"message" (channel, message)**:
Client will emit `message` for every message received that matches an active subscription.
Listeners are passed the channel name as `channel` and the message as `message`.
-### "pmessage" (pattern, channel, message)
+**"pmessage" (pattern, channel, message)**:
Client will emit `pmessage` for every message received that matches an active
subscription pattern. Listeners are passed the original pattern used with
`PSUBSCRIBE` as `pattern`, the sending channel name as `channel`, and the
message as `message`.
-### "message_buffer" (channel, message)
+**"message_buffer" (channel, message)**:
This is the same as the `message` event with the exception, that it is always
going to emit a buffer. If you listen to the `message` event at the same time as
the `message_buffer`, it is always going to emit a string.
-### "pmessage_buffer" (pattern, channel, message)
+**"pmessage_buffer" (pattern, channel, message)**:
This is the same as the `pmessage` event with the exception, that it is always
going to emit a buffer. If you listen to the `pmessage` event at the same time
as the `pmessage_buffer`, it is always going to emit a string.
-### "subscribe" (channel, count)
+**"subscribe" (channel, count)**:
Client will emit `subscribe` in response to a `SUBSCRIBE` command. Listeners are
passed the channel name as `channel` and the new count of subscriptions for this
client as `count`.
-### "psubscribe" (pattern, count)
+**"psubscribe" (pattern, count)**:
Client will emit `psubscribe` in response to a `PSUBSCRIBE` command. Listeners
are passed the original pattern as `pattern`, and the new count of subscriptions
for this client as `count`.
-### "unsubscribe" (channel, count)
+**"unsubscribe" (channel, count)**:
Client will emit `unsubscribe` in response to a `UNSUBSCRIBE` command. Listeners
are passed the channel name as `channel` and the new count of subscriptions for
this client as `count`. When `count` is 0, this client has left subscriber mode
and no more subscriber events will be emitted.
-### "punsubscribe" (pattern, count)
+**"punsubscribe" (pattern, count)**:
Client will emit `punsubscribe` in response to a `PUNSUBSCRIBE` command.
Listeners are passed the channel name as `channel` and the new count of
subscriptions for this client as `count`. When `count` is 0, this client has
left subscriber mode and no more subscriber events will be emitted.
-## client.multi([commands])
+### client.multi([commands])
`MULTI` commands are queued up until an `EXEC` is issued, and then all commands
are run atomically by Redis. The interface in `node_redis` is to return an
individual `Multi` object by calling `client.multi()`. If any command fails to
queue, all commands are rolled back and none is going to be executed (For
-further information look at
-[transactions](http://redis.io/topics/transactions)).
+further information see the [Redis transactions](http://redis.io/topics/transactions) documentation).
```js
-var redis = require("./index"),
- client = redis.createClient(),
- set_size = 20;
+const redis = require("redis");
+const client = redis.createClient();
-client.sadd("bigset", "a member");
-client.sadd("bigset", "another member");
+let setSize = 20;
-while (set_size > 0) {
- client.sadd("bigset", "member " + set_size);
- set_size -= 1;
+client.sadd("key", "member1");
+client.sadd("key", "member2");
+
+while (setSize > 0) {
+ client.sadd("key", "member" + setSize);
+ setSize -= 1;
}
-// multi chain with an individual callback
+// chain commands
client
.multi()
- .scard("bigset")
- .smembers("bigset")
- .keys("*", function(err, replies) {
- // NOTE: code in this callback is NOT atomic
- // this only happens after the the .exec call finishes.
- client.mget(replies, redis.print);
- })
+ .scard("key")
+ .smembers("key")
+ .keys("*")
.dbsize()
.exec(function(err, replies) {
console.log("MULTI got " + replies.length + " replies");
replies.forEach(function(reply, index) {
- console.log("Reply " + index + ": " + reply.toString());
+ console.log("REPLY @ index " + index + ": " + reply.toString());
});
});
```
-### Multi.exec([callback])
+#### Multi.exec([callback])
`client.multi()` is a constructor that returns a `Multi` object. `Multi` objects
share all of the same command methods as `client` objects do. Commands are
queued up inside the `Multi` object until `Multi.exec()` is invoked.
-If your code contains an syntax error an EXECABORT error is going to be thrown
+If your code contains an syntax error an `EXECABORT` error is going to be thrown
and all commands are going to be aborted. That error contains a `.errors`
property that contains the concrete errors.
If all commands were queued successfully and an error is thrown by redis while
processing the commands that error is going to be returned in the result array!
-No other command is going to be aborted though than the onces failing.
+No other command is going to be aborted though than the ones failing.
You can either chain together `MULTI` commands as in the above example, or you
can queue individual commands while still sending regular client command as in
From 24824efdcc838d753f93bdec9572eca099b5d4ad Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 03:58:55 +0000
Subject: [PATCH 65/96] remove deprecated `new Buffer()` usage
---
benchmarks/multi_bench.js | 6 +++---
index.js | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/benchmarks/multi_bench.js b/benchmarks/multi_bench.js
index a79d92e83c..86cf9329ce 100644
--- a/benchmarks/multi_bench.js
+++ b/benchmarks/multi_bench.js
@@ -213,11 +213,11 @@ Test.prototype.print_stats = function () {
};
small_str = '1234';
-small_buf = new Buffer(small_str);
+small_buf = Buffer.from(small_str);
large_str = (new Array(4096 + 1).join('-'));
-large_buf = new Buffer(large_str);
+large_buf = Buffer.from(large_str);
very_large_str = (new Array((4 * 1024 * 1024) + 1).join('-'));
-very_large_buf = new Buffer(very_large_str);
+very_large_buf = Buffer.from(very_large_str);
tests.push(new Test({descr: 'PING', command: 'ping', args: []}));
tests.push(new Test({descr: 'PING', command: 'ping', args: [], batch: 50}));
diff --git a/index.js b/index.js
index bdbf46daf5..6cea8bd4c6 100644
--- a/index.js
+++ b/index.js
@@ -829,7 +829,7 @@ RedisClient.prototype.internal_send_command = function (command_obj) {
// 30000 seemed to be a good value to switch to buffers after testing and checking the pros and cons
if (args[i].length > 30000) {
big_data = true;
- args_copy[i] = new Buffer(args[i], 'utf8');
+ args_copy[i] = Buffer.from(args[i], 'utf8');
} else {
args_copy[i] = args[i];
}
From 30dd8cf8796d96c239d4324be42f689806685812 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 03:59:02 +0000
Subject: [PATCH 66/96] docs
---
README.md | 411 ++++++++++++++++++++++++++----------------------------
1 file changed, 195 insertions(+), 216 deletions(-)
diff --git a/README.md b/README.md
index 94b70f8396..236a214b5c 100644
--- a/README.md
+++ b/README.md
@@ -308,6 +308,7 @@ const assert = require("assert");
const redis = require("redis");
const { AbortError, AggregateError, ReplyError } = require("redis");
+
const client = redis.createClient();
client.on("error", function(err) {
@@ -565,21 +566,22 @@ can queue individual commands while still sending regular client command as in
this example:
```js
-var redis = require("redis"),
- client = redis.createClient(),
- multi;
+const redis = require("redis");
+const client = redis.createClient();
// start a separate multi command queue
-multi = client.multi();
-multi.incr("incr thing", redis.print);
-multi.incr("incr other thing", redis.print);
+const multi = client.multi();
-// runs immediately
-client.mset("incr thing", 100, "incr other thing", 1, redis.print);
+// add some commands to the queue
+multi.incr("count_cats", redis.print);
+multi.incr("count_dogs", redis.print);
-// drains multi queue and runs atomically
+// runs a command immediately outside of the `multi` instance
+client.mset("count_cats", 100, "count_dogs", 50, redis.print);
+
+// drains the multi queue and runs each command atomically
multi.exec(function(err, replies) {
- console.log(replies); // 101, 2
+ console.log(replies); // 101, 51
});
```
@@ -587,43 +589,26 @@ In addition to adding commands to the `MULTI` queue individually, you can also
pass an array of commands and arguments to the constructor:
```js
-var redis = require("redis"),
- client = redis.createClient();
+const redis = require("redis");
+
+const client = redis.createClient();
client
.multi([
- ["mget", "multifoo", "multibar", redis.print],
- ["incr", "multifoo"],
- ["incr", "multibar"],
+ ["mget", "foo", "bar", redis.print],
+ ["incr", "hello"],
])
.exec(function(err, replies) {
console.log(replies);
});
```
-### Multi.exec_atomic([callback])
+#### Multi.exec_atomic([callback])
Identical to Multi.exec but with the difference that executing a single command
will not use transactions.
-## client.batch([commands])
-
-Identical to .multi without transactions. This is recommended if you want to
-execute many commands at once but don't have to rely on transactions.
-
-`BATCH` commands are queued up until an `EXEC` is issued, and then all commands
-are run atomically by Redis. The interface in `node_redis` is to return an
-individual `Batch` object by calling `client.batch()`. The only difference
-between .batch and .multi is that no transaction is going to be used.
-Be aware that the errors are - just like in multi statements - in the result.
-Otherwise both, errors and results could be returned at the same time.
-
-If you fire many commands at once this is going to boost the execution speed
-significantly compared to firing the same commands in a loop without waiting for
-the result! See the benchmarks for further comparison. Please remember that all
-commands are kept in memory until they are fired.
-
-## Optimistic Locks
+#### Optimistic Locks
Using `multi` you can make sure your modifications run as a transaction, but you
can't be sure you got there first. What if another client modified a key while
@@ -633,39 +618,39 @@ To solve this, Redis supports the [WATCH](https://redis.io/topics/transactions)
command, which is meant to be used with MULTI:
```js
-var redis = require("redis"),
- client = redis.createClient({ ... });
+const redis = require("redis");
-client.watch("foo", function( err ){
- if(err) throw err;
+const client = redis.createClient();
- client.get("foo", function(err, result) {
- if(err) throw err;
+client.watch("foo", function(watchError) {
+ if (watchError) throw watchError;
- // Process result
- // Heavy and time consuming operation here
+ client.get("foo", function(getError, result) {
+ if (getError) throw getError;
- client.multi()
- .set("foo", "some heavy computation")
- .exec(function(err, results) {
+ // Process result
+ // Heavy and time consuming operation here to generate "bar"
- /**
- * If err is null, it means Redis successfully attempted
- * the operation.
- */
- if(err) throw err;
+ client
+ .multi()
+ .set("foo", "bar")
+ .exec(function(execError, results) {
+ /**
+ * If err is null, it means Redis successfully attempted
+ * the operation.
+ */
+ if (execError) throw err;
- /**
- * If results === null, it means that a concurrent client
- * changed the key while we were processing it and thus
- * the execution of the MULTI command was not performed.
- *
- * NOTICE: Failing an execution of MULTI is not considered
- * an error. So you will have err === null and results === null
- */
-
- });
- });
+ /**
+ * If results === null, it means that a concurrent client
+ * changed the key while we were processing it and thus
+ * the execution of the MULTI command was not performed.
+ *
+ * NOTICE: Failing an execution of MULTI is not considered
+ * an error. So you will have err === null and results === null
+ */
+ });
+ });
});
```
@@ -681,14 +666,18 @@ client cannot connect to Redis.
An example where we can see the execution of a `multi` command fail is as follows:
```js
-let clients = {};
-clients.watcher = redis.createClient({ ... } );
-clients.alterer = clients.watcher.duplicate();
+const clients = {
+ watcher: redis.createClient(),
+ modifier: redis.createClient(),
+};
-clients.watcher.watch('foo',function(err) {
- if (err) { throw err; }
- //if you comment out the next line, the transaction will work
- clients.alterer.set('foo',Math.random(), (err) => {if (err) { throw err; }});
+clients.watcher.watch("foo", function(watchError) {
+ if (watchError) throw watchError;
+
+ // if you comment out the next line, the transaction will work
+ clients.modifier.set("foo", Math.random(), setError => {
+ if (setError) throw err;
+ });
//using a setTimeout here to ensure that the MULTI/EXEC will come after the SET.
//Normally, you would use a callback to ensure order, but I want the above SET command
@@ -696,23 +685,25 @@ clients.watcher.watch('foo',function(err) {
setTimeout(function() {
clients.watcher
.multi()
- .set('foo','abc')
- .set('bar','1234')
- .exec((err,results) => {
- if (err) { throw err; }
+ .set("foo", "bar")
+ .set("hello", "world")
+ .exec((multiExecError, results) => {
+ if (multiExecError) throw multiExecError;
+
if (results === null) {
- console.log('transaction aborted because results were null');
+ console.log("transaction aborted because results were null");
} else {
- console.log('transaction worked and returned',results)
+ console.log("transaction worked and returned", results);
}
+
clients.watcher.quit();
- clients.alterer.quit();
+ clients.modifier.quit();
});
- },1000);
+ }, 1000);
});
```
-### WATCH limitations
+#### `WATCH` limitations
Redis WATCH works only on _whole_ key values. For example, with WATCH you can
watch a hash for modifications, but you cannot watch a specific field of a hash.
@@ -721,31 +712,49 @@ The following example would watch the keys `foo` and `hello`, not the field `hel
of hash `foo`:
```js
-var redis = require("redis"),
- client = redis.createClient({ ... });
+const redis = require("redis");
-client.hget( "foo", "hello", function(err, result){
+const client = redis.createClient();
- //Do some processing with the value from this field and watch it after
+client.hget("foo", "hello", function(hashGetError, result) {
+ if (hashGetError) throw hashGetError;
- client.watch("foo", "hello", function( err ){
- if(err) throw err;
+ //Do some processing with the value from this field and watch it after
- /**
- * WRONG: This is now watching the keys 'foo' and 'hello'. It is not
- * watching the field 'hello' of hash 'foo'. Because the key 'foo'
- * refers to a hash, this command is now watching the entire hash
- * for modifications.
- */
- });
-} )
+ client.watch("foo", "hello", function(watchError) {
+ if (watchError) throw watchError;
+ /**
+ * This is now watching the keys 'foo' and 'hello'. It is not
+ * watching the field 'hello' of hash 'foo'. Because the key 'foo'
+ * refers to a hash, this command is now watching the entire hash
+ * for modifications.
+ */
+ });
+});
```
-This limitation also applies to sets ( cannot watch individual set members )
+This limitation also applies to sets (you can not watch individual set members)
and any other collections.
-## Monitor mode
+### client.batch([commands])
+
+Identical to `.multi()` without transactions. This is recommended if you want to
+execute many commands at once but don't need to rely on transactions.
+
+`BATCH` commands are queued up until an `EXEC` is issued, and then all commands
+are run atomically by Redis. The interface in `node_redis` is to return an
+individual `Batch` object by calling `client.batch()`. The only difference
+between .batch and .multi is that no transaction is going to be used.
+Be aware that the errors are - just like in multi statements - in the result.
+Otherwise both, errors and results could be returned at the same time.
+
+If you fire many commands at once this is going to boost the execution speed
+significantly compared to firing the same commands in a loop without waiting for
+the result! See the benchmarks for further comparison. Please remember that all
+commands are kept in memory until they are fired.
+
+### Monitor mode
Redis supports the `MONITOR` command, which lets you see all commands received
by the Redis server across all client connections, including from other client
@@ -756,25 +765,28 @@ connected to the server including the monitoring client itself. The callback for
the `monitor` event takes a timestamp from the Redis server, an array of command
arguments and the raw monitoring string.
-Example:
+#### Example:
```js
-var client = require("redis").createClient();
+const redis = require("redis");
+const client = redis.createClient();
+
client.monitor(function(err, res) {
console.log("Entering monitoring mode.");
});
+
client.set("foo", "bar");
-client.on("monitor", function(time, args, raw_reply) {
+client.on("monitor", function(time, args, rawReply) {
console.log(time + ": " + args); // 1458910076.446514:['set', 'foo', 'bar']
});
```
-# Extras
+## Extras
-Some other things you might like to know about.
+Some other things you might find useful.
-## client.server_info
+### `client.server_info`
After the ready probe completes, the results from the INFO command are saved in
the `client.server_info` object.
@@ -782,47 +794,45 @@ the `client.server_info` object.
The `versions` key contains an array of the elements of the version string for
easy comparison.
- > client.server_info.redis_version
- '2.3.0'
- > client.server_info.versions
- [ 2, 3, 0 ]
+```
+> client.server_info.redis_version
+'2.3.0'
+> client.server_info.versions
+[ 2, 3, 0 ]
+```
-## redis.print()
+### `redis.print()`
A handy callback function for displaying return values when testing. Example:
```js
-var redis = require("redis"),
- client = redis.createClient();
+const redis = require("redis");
+const client = redis.createClient();
client.on("connect", function() {
- client.set("foo_rand000000000000", "some fantastic value", redis.print);
- client.get("foo_rand000000000000", redis.print);
+ client.set("foo", "bar", redis.print); // => "Reply: OK"
+ client.get("foo", redis.print); // => "Reply: bar"
+ client.quit();
});
```
-This will print:
-
- Reply: OK
- Reply: some fantastic value
-
-Note that this program will not exit cleanly because the client is still connected.
-
-## Multi-word commands
+### Multi-word commands
To execute redis multi-word commands like `SCRIPT LOAD` or `CLIENT LIST` pass
the second word as first parameter:
```js
client.script("load", "return 1");
+
client
.multi()
.script("load", "return 1")
.exec();
+
client.multi([["script", "load", "return 1"]]).exec();
```
-## client.duplicate([options][, callback])
+### `client.duplicate([options][, callback])`
Duplicate all current options and return a new redisClient instance. All options
passed to the duplicate function are going to replace the original option. If
@@ -832,36 +842,13 @@ to return an error instead in the callback.
One example of when to use duplicate() would be to accommodate the connection-
blocking redis commands BRPOP, BLPOP, and BRPOPLPUSH. If these commands
-are used on the same redisClient instance as non-blocking commands, the
+are used on the same Redis client instance as non-blocking commands, the
non-blocking ones may be queued up until after the blocking ones finish.
-```js
-var Redis = require("redis");
-var client = Redis.createClient();
-var clientBlocking = client.duplicate();
-
-var get = function() {
- console.log("get called");
- client.get("any_key", function() {
- console.log("get returned");
- });
- setTimeout(get, 1000);
-};
-var brpop = function() {
- console.log("brpop called");
- clientBlocking.brpop("nonexistent", 5, function() {
- console.log("brpop return");
- setTimeout(brpop, 1000);
- });
-};
-get();
-brpop();
-```
-
Another reason to use duplicate() is when multiple DBs on the same server are
accessed via the redis SELECT command. Each DB could use its own connection.
-## client.send_command(command_name[, [args][, callback]])
+### `client.send_command(command_name[, [args][, callback]])`
All Redis commands have been added to the `client` object. However, if new
commands are introduced before this library is updated or if you want to add
@@ -871,23 +858,23 @@ Redis.
All commands are sent as multi-bulk commands. `args` can either be an Array of
arguments, or omitted / set to undefined.
-## redis.add_command(command_name)
+### `redis.add_command(command_name)`
Calling add_command will add a new command to the prototype. The exact command
name will be used when calling using this new command. Using arbitrary arguments
is possible as with any other command.
-## client.connected
+### `client.connected`
Boolean tracking the state of the connection to the Redis server.
-## client.command_queue_length
+### `client.command_queue_length`
The number of commands that have been sent to the Redis server but not yet
replied to. You can use this to enforce some kind of maximum queue depth for
commands while connected.
-## client.offline_queue_length
+### `client.offline_queue_length`
The number of commands that have been queued up for a future connection. You can
use this to enforce some kind of maximum queue depth for pre-connection
@@ -897,31 +884,32 @@ commands.
This applies to anything that uses an optional `[WITHSCORES]` or `[LIMIT offset count]` in the [redis.io/commands](http://redis.io/commands) documentation.
-Example:
+#### Example
```js
-var args = ["myzset", 1, "one", 2, "two", 3, "three", 99, "ninety-nine"];
-client.zadd(args, function(err, response) {
- if (err) throw err;
- console.log("added " + response + " items.");
+const args = ["myzset", 1, "one", 2, "two", 3, "three", 99, "ninety-nine"];
+
+client.zadd(args, function(addError, addResponse) {
+ if (addError) throw addError;
+ console.log("added " + addResponse + " items.");
// -Infinity and +Infinity also work
- var args1 = ["myzset", "+inf", "-inf"];
- client.zrevrangebyscore(args1, function(err, response) {
- if (err) throw err;
- console.log("example1", response);
- // write your code here
+ const args1 = ["myzset", "+inf", "-inf"];
+ client.zrevrangebyscore(args1, function(rangeError, rangeResponse) {
+ if (rangeError) throw rangeError;
+ console.log("response1", rangeResponse);
+ // ...
});
- var max = 3,
- min = 1,
- offset = 1,
- count = 2;
- var args2 = ["myzset", max, min, "WITHSCORES", "LIMIT", offset, count];
- client.zrevrangebyscore(args2, function(err, response) {
- if (err) throw err;
- console.log("example2", response);
- // write your code here
+ const max = 3;
+ const min = 1;
+ const offset = 1;
+ const count = 2;
+ const args2 = ["myzset", max, min, "WITHSCORES", "LIMIT", offset, count];
+ client.zrevrangebyscore(args2, function(rangeError, rangeResponse) {
+ if (rangeError) throw rangeError;
+ console.log("response2", rangeResponse);
+ // ...
});
});
```
@@ -932,42 +920,42 @@ Much effort has been spent to make `node_redis` as fast as possible for common
operations.
```
-Lenovo T450s, i7-5600U and 12gb memory
-clients: 1, NodeJS: 6.2.0, Redis: 3.2.0, parser: javascript, connected by: tcp
- PING, 1/1 avg/max: 0.02/ 5.26 2501ms total, 46916 ops/sec
- PING, batch 50/1 avg/max: 0.06/ 4.35 2501ms total, 755178 ops/sec
- SET 4B str, 1/1 avg/max: 0.02/ 4.75 2501ms total, 40856 ops/sec
- SET 4B str, batch 50/1 avg/max: 0.11/ 1.51 2501ms total, 432727 ops/sec
- SET 4B buf, 1/1 avg/max: 0.05/ 2.76 2501ms total, 20659 ops/sec
- SET 4B buf, batch 50/1 avg/max: 0.25/ 1.76 2501ms total, 194962 ops/sec
- GET 4B str, 1/1 avg/max: 0.02/ 1.55 2501ms total, 45156 ops/sec
- GET 4B str, batch 50/1 avg/max: 0.09/ 3.15 2501ms total, 524110 ops/sec
- GET 4B buf, 1/1 avg/max: 0.02/ 3.07 2501ms total, 44563 ops/sec
- GET 4B buf, batch 50/1 avg/max: 0.10/ 3.18 2501ms total, 473171 ops/sec
- SET 4KiB str, 1/1 avg/max: 0.03/ 1.54 2501ms total, 32627 ops/sec
- SET 4KiB str, batch 50/1 avg/max: 0.34/ 1.89 2501ms total, 146861 ops/sec
- SET 4KiB buf, 1/1 avg/max: 0.05/ 2.85 2501ms total, 20688 ops/sec
- SET 4KiB buf, batch 50/1 avg/max: 0.36/ 1.83 2501ms total, 138165 ops/sec
- GET 4KiB str, 1/1 avg/max: 0.02/ 1.37 2501ms total, 39389 ops/sec
- GET 4KiB str, batch 50/1 avg/max: 0.24/ 1.81 2501ms total, 208157 ops/sec
- GET 4KiB buf, 1/1 avg/max: 0.02/ 2.63 2501ms total, 39918 ops/sec
- GET 4KiB buf, batch 50/1 avg/max: 0.31/ 8.56 2501ms total, 161575 ops/sec
- INCR, 1/1 avg/max: 0.02/ 4.69 2501ms total, 45685 ops/sec
- INCR, batch 50/1 avg/max: 0.09/ 3.06 2501ms total, 539964 ops/sec
- LPUSH, 1/1 avg/max: 0.02/ 3.04 2501ms total, 41253 ops/sec
- LPUSH, batch 50/1 avg/max: 0.12/ 1.94 2501ms total, 425090 ops/sec
- LRANGE 10, 1/1 avg/max: 0.02/ 2.28 2501ms total, 39850 ops/sec
- LRANGE 10, batch 50/1 avg/max: 0.25/ 1.85 2501ms total, 194302 ops/sec
- LRANGE 100, 1/1 avg/max: 0.05/ 2.93 2501ms total, 21026 ops/sec
- LRANGE 100, batch 50/1 avg/max: 1.52/ 2.89 2501ms total, 32767 ops/sec
- SET 4MiB str, 1/1 avg/max: 5.16/ 15.55 2502ms total, 193 ops/sec
- SET 4MiB str, batch 20/1 avg/max: 89.73/ 99.96 2513ms total, 223 ops/sec
- SET 4MiB buf, 1/1 avg/max: 2.23/ 8.35 2501ms total, 446 ops/sec
- SET 4MiB buf, batch 20/1 avg/max: 41.47/ 50.91 2530ms total, 482 ops/sec
- GET 4MiB str, 1/1 avg/max: 2.79/ 10.91 2502ms total, 358 ops/sec
- GET 4MiB str, batch 20/1 avg/max: 101.61/118.11 2541ms total, 197 ops/sec
- GET 4MiB buf, 1/1 avg/max: 2.32/ 14.93 2502ms total, 430 ops/sec
- GET 4MiB buf, batch 20/1 avg/max: 65.01/ 84.72 2536ms total, 308 ops/sec
+Mac mini (2018), i7-3.2GHz and 32gb memory
+clients: 1, NodeJS: 12.15.0, Redis: 5.0.6, parser: javascript, connected by: tcp
+ PING, 1/1 avg/max: 0.03/ 3.28 2501ms total, 31926 ops/sec
+ PING, batch 50/1 avg/max: 0.08/ 3.35 2501ms total, 599460 ops/sec
+ SET 4B str, 1/1 avg/max: 0.03/ 3.54 2501ms total, 29483 ops/sec
+ SET 4B str, batch 50/1 avg/max: 0.10/ 1.39 2501ms total, 477689 ops/sec
+ SET 4B buf, 1/1 avg/max: 0.04/ 1.52 2501ms total, 23449 ops/sec
+ SET 4B buf, batch 50/1 avg/max: 0.20/ 2.09 2501ms total, 244382 ops/sec
+ GET 4B str, 1/1 avg/max: 0.03/ 1.35 2501ms total, 32205 ops/sec
+ GET 4B str, batch 50/1 avg/max: 0.09/ 2.02 2501ms total, 568992 ops/sec
+ GET 4B buf, 1/1 avg/max: 0.03/ 2.93 2501ms total, 32802 ops/sec
+ GET 4B buf, batch 50/1 avg/max: 0.08/ 1.03 2501ms total, 592863 ops/sec
+ SET 4KiB str, 1/1 avg/max: 0.03/ 0.76 2501ms total, 29287 ops/sec
+ SET 4KiB str, batch 50/1 avg/max: 0.35/ 2.97 2501ms total, 143163 ops/sec
+ SET 4KiB buf, 1/1 avg/max: 0.04/ 1.21 2501ms total, 23070 ops/sec
+ SET 4KiB buf, batch 50/1 avg/max: 0.28/ 2.34 2501ms total, 176809 ops/sec
+ GET 4KiB str, 1/1 avg/max: 0.03/ 1.54 2501ms total, 29555 ops/sec
+ GET 4KiB str, batch 50/1 avg/max: 0.18/ 1.59 2501ms total, 279188 ops/sec
+ GET 4KiB buf, 1/1 avg/max: 0.03/ 1.80 2501ms total, 30681 ops/sec
+ GET 4KiB buf, batch 50/1 avg/max: 0.17/ 5.00 2501ms total, 285886 ops/sec
+ INCR, 1/1 avg/max: 0.03/ 1.99 2501ms total, 32757 ops/sec
+ INCR, batch 50/1 avg/max: 0.09/ 2.54 2501ms total, 538964 ops/sec
+ LPUSH, 1/1 avg/max: 0.05/ 4.85 2501ms total, 19482 ops/sec
+ LPUSH, batch 50/1 avg/max: 0.12/ 9.52 2501ms total, 395562 ops/sec
+ LRANGE 10, 1/1 avg/max: 0.06/ 9.21 2501ms total, 17062 ops/sec
+ LRANGE 10, batch 50/1 avg/max: 0.22/ 1.03 2501ms total, 228269 ops/sec
+ LRANGE 100, 1/1 avg/max: 0.05/ 1.44 2501ms total, 19051 ops/sec
+ LRANGE 100, batch 50/1 avg/max: 0.99/ 3.46 2501ms total, 50480 ops/sec
+ SET 4MiB str, 1/1 avg/max: 4.11/ 13.96 2501ms total, 243 ops/sec
+ SET 4MiB str, batch 20/1 avg/max: 91.16/145.01 2553ms total, 219 ops/sec
+ SET 4MiB buf, 1/1 avg/max: 2.81/ 11.90 2502ms total, 354 ops/sec
+ SET 4MiB buf, batch 20/1 avg/max: 36.21/ 70.96 2535ms total, 552 ops/sec
+ GET 4MiB str, 1/1 avg/max: 2.82/ 19.10 2503ms total, 354 ops/sec
+ GET 4MiB str, batch 20/1 avg/max: 128.57/207.86 2572ms total, 156 ops/sec
+ GET 4MiB buf, 1/1 avg/max: 3.13/ 23.88 2501ms total, 318 ops/sec
+ GET 4MiB buf, batch 20/1 avg/max: 65.91/ 87.59 2572ms total, 303 ops/sec
```
## Debugging
@@ -983,7 +971,8 @@ Good stack traces are only activated in development and debug mode as this
results in a significant performance penalty.
**_Comparison_**:
-Useless stack trace:
+
+Standard stack trace:
```
ReplyError: ERR wrong number of arguments for 'set' command
@@ -991,7 +980,7 @@ ReplyError: ERR wrong number of arguments for 'set' command
at parseType (/home/ruben/repos/redis/node_modules/redis-parser/lib/parser.js:219:14)
```
-Good stack trace:
+Debug stack trace:
```
ReplyError: ERR wrong number of arguments for 'set' command
@@ -1009,20 +998,10 @@ ReplyError: ERR wrong number of arguments for 'set' command
at processImmediate [as _immediateCallback] (timers.js:383:17)
```
-## How to Contribute
+## Contributing
-- Open a pull request or an issue about what you want to implement / change. We're glad for any help!
-- Please be aware that we'll only accept fully tested code.
-
-## Contributors
-
-The original author of node_redis is [Matthew Ranney](https://github.com/mranney)
-
-The current lead maintainer is [Ruben Bridgewater](https://github.com/BridgeAR)
-
-Many [others](https://github.com/NodeRedis/node_redis/graphs/contributors)
-contributed to `node_redis` too. Thanks to all of them!
+Please see the [contributing guide](CONTRIBUTING.md).
## License
-[MIT](LICENSE)
+This repository is licensed under the "MIT" license. See [LICENSE](LICENSE).
From d92665d931379f74e94e5c63ddf94d3a275b1d45 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 04:48:48 +0000
Subject: [PATCH 67/96] docs
---
.github/ISSUE_TEMPLATE.md | 39 ++++++++---
.github/PULL_REQUEST_TEMPLATE.md | 20 +++---
CONTRIBUTING.md | 107 ++++++++++++++++++++++++++++++-
3 files changed, 147 insertions(+), 19 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 42f2d3eeb6..c74eb12b80 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,15 +1,34 @@
-_Thanks for wanting to report an issue you've found in node_redis. Please delete
+---
+title: ⚠️ Bug report
+labels: needs-triage
+---
+
+### Issue
+
+
-* **Version**: What node_redis and what redis version is the issue happening on?
-* **Platform**: What platform / version? (For example Node.js 0.10 or Node.js 5.7.0 on Windows 7 / Ubuntu 15.10 / Azure)
-* **Description**: Description of your issue, stack traces from errors and code that reproduces the issue
+> Describe your issue here
-[gitter]: https://gitter.im/NodeRedis/node_redis?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
\ No newline at end of file
+
+---
+
+### Environment
+
+
+ - **Node.js Version**: `VERSION_HERE`
+
+
+ - **Redis Version**: `VERSION_HERE`
+
+
+ - **Platform**: `PLATFORM_HERE`
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 9706621c1b..5c29bc26e2 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,14 +1,18 @@
-### Pull Request check-list
+### Description
-_Please make sure to review and check all of these items:_
+
+
+
+
+
+
+### Check List
+
+
- [ ] Does `npm test` pass with this change (including linting)?
- [ ] Is the new or changed code fully tested?
- [ ] Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?
-_NOTE: these things are not required to open a PR and can be done
-afterwards / while the PR is open._
-
-### Description of change
-
-_Please provide a description of the change here._
\ No newline at end of file
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index cf873b4c07..e82846fbee 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1 +1,106 @@
-
+# Introduction
+
+First, thank you for considering contributing to Node Redis! It's people like you that make the open source community such a great community! 😊
+
+We welcome any type of contribution, not just code. You can help with;
+
+- **QA**: file bug reports, the more details you can give the better (e.g. platform versions, screenshots sdk versions & logs)
+- **Docs**: improve reference coverage, add more examples, fix typos or anything else you can spot. At the top of every page on our docs site you can click the `Edit` pencil to go to that pages markdown file, or view the [Docs Repo](https://github.com/invertase/react-native-firebase-docs) directly
+- **Code**: take a look at the open issues. Even if you can't write code, commenting on them, showing that you care about a given issue matters.
+- **Donations**: we welcome financial contributions in full transparency on our [open collective](https://opencollective.com/node-redis).
+
+---
+
+## Project Guidelines
+
+As maintainers of this project, we want to ensure that the project lives and continues to grow. Not blocked by any
+singular person's time.
+
+One of the simplest ways of doing this is by encouraging a larger set of shallow contributors. Through this we hope to
+mitigate the problems of a project that needs updates but there is no-one who has the power to do so.
+
+### Continuous Deployment
+
+
+Coming soon.
+
+### How can we help you get comfortable contributing?
+
+It is normal for a first pull request to be a potential fix for a problem but moving on from there to helping the
+project's direction can be difficult.
+
+We try to help contributors cross that barrier by offering good first step issues (labelled `good-first-issue`). These
+issues can be fixed without feeling like you are stepping on toes. Generally, these should be non-critical issues that
+are well defined. They will be purposely avoided by mature contributors to the project, to make space for others.
+
+Additionally issues labelled `needs-triage` or `help-wanted` can also be picked up, these may not necessarily require
+code changes but rather help with debugging and finding the cause of the issue whether it's a bug or a users incorrect
+setup of the library or project.
+
+We aim to keep all project discussion inside GitHub issues. This is to make sure valuable discussion is accessible via
+search. If you have questions about how to use the library, or how the project is running - GitHub issues are the goto
+tool for this project.
+
+### Our expectations on you as a contributor
+
+You shouldn't feel bad for not contributing to open source. We want contributors like yourself to provide ideas, keep
+the ship shipping and to take some of the load from others. It is non-obligatory; we’re here to get things done in an
+enjoyable way. :trophy:
+
+We only ask that you follow the conduct guidelines set out in our [Code of Conduct](/CODE_OF_CONDUCT.md) throughout your
+contribution journey.
+
+### What about if you have problems that cannot be discussed in public?
+
+You can reach out to us directly via email (`redis[AT]invertase.io`) or direct message us on
+[Twitter](https://twitter.com/NodeRedis) if you'd like to discuss something privately.
+
+#### Project Maintainers
+
+ - Mike Diarmid ([Salakar](https://github.com/Salakar)) @ [Invertase](https://invertase.io)
+ - Twitter: [@mikediarmid](https://twitter.com/mikediarmid)
+ - Elliot Hesp ([Ehesp](https://github.com/Ehesp)) @ [Invertase](https://invertase.io)
+ - Twitter: [@elliothesp](https://twitter.com/elliothesp)
+ - Ruben Bridgewater ([BridgeAR](https://github.com/BridgeAR))
+ - Twitter: [@BridgeAR](https://twitter.com/BridgeAR)
+
+Huge thanks to the original author of Node Redis, [Matthew Ranney](https://github.com/mranney) and also to
+[Ruben Bridgewater](https://github.com/BridgeAR) for handing over this project over to new maintainers so it could be
+continuously maintained.
+
+---
+
+## Code Guidelines
+
+### Your First Contribution
+
+Working on your first Pull Request? You can learn how from this _free_ series,
+[How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github).
+
+### Testing Code
+
+Node Redis has a full test suite with coverage setup.
+
+To run the tests use the `npm test` command. To check detailed coverage locally run the `npm run coverage` command after
+testing and open the generated `./coverage/index.html` in your browser.
+
+### Submitting code for review
+
+The bigger the pull request, the longer it will take to review and merge. Where possible try to break down large pull
+requests into smaller chunks that are easier to review and merge. It is also always helpful to have some context for
+your pull request. What was the purpose? Why does it matter to you? What problem are you trying to solve? Tag in any linked issues.
+
+To aid review we also ask that you fill out the pull request template as much as possible.
+
+> Use a `draft` pull request if your pull request is not complete or ready for review.
+
+### Code review process
+
+Pull Requests to the protected branches require two or more peer-review approvals and passing status checks to be able
+to be merged.
+
+When reviewing a Pull Request please check the following steps on top of the existing automated checks:
+
+- Does the it provide or update the docs if docs changes are required?
+- Have the tests been updated or new tests been added to test any newly implemented or changed functionality?
+- Is the testing coverage ok and not worse than previously?
From bf673baca70a156695ae8c860a64d06ffb65832c Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 04:50:48 +0000
Subject: [PATCH 68/96] docs
---
CONTRIBUTING.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e82846fbee..b7bc2c3b17 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,8 +5,8 @@ First, thank you for considering contributing to Node Redis! It's people like yo
We welcome any type of contribution, not just code. You can help with;
- **QA**: file bug reports, the more details you can give the better (e.g. platform versions, screenshots sdk versions & logs)
-- **Docs**: improve reference coverage, add more examples, fix typos or anything else you can spot. At the top of every page on our docs site you can click the `Edit` pencil to go to that pages markdown file, or view the [Docs Repo](https://github.com/invertase/react-native-firebase-docs) directly
-- **Code**: take a look at the open issues. Even if you can't write code, commenting on them, showing that you care about a given issue matters.
+- **Docs**: improve reference coverage, add more examples, fix typos or anything else you can spot.
+- **Code**: take a look at the open issues and help triage them.
- **Donations**: we welcome financial contributions in full transparency on our [open collective](https://opencollective.com/node-redis).
---
From f45850505d9ad31286c55b07edb0d31457b0be96 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 04:54:12 +0000
Subject: [PATCH 69/96] docs
---
.github/PULL_REQUEST_TEMPLATE.md | 7 ++++++-
CONTRIBUTING.md | 4 ++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 5c29bc26e2..98e3d31260 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,12 +1,17 @@
+
+
### Description
+> Description your pull request here
-### Check List
+---
+
+### Checklist
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b7bc2c3b17..192219267a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -57,9 +57,9 @@ You can reach out to us directly via email (`redis[AT]invertase.io`) or direct m
#### Project Maintainers
- - Mike Diarmid ([Salakar](https://github.com/Salakar)) @ [Invertase](https://invertase.io)
+ - Mike Diarmid ([Salakar](https://github.com/Salakar)) @ [Invertase](https://github.com/invertase)
- Twitter: [@mikediarmid](https://twitter.com/mikediarmid)
- - Elliot Hesp ([Ehesp](https://github.com/Ehesp)) @ [Invertase](https://invertase.io)
+ - Elliot Hesp ([Ehesp](https://github.com/Ehesp)) @ [Invertase](https://github.com/invertase)
- Twitter: [@elliothesp](https://twitter.com/elliothesp)
- Ruben Bridgewater ([BridgeAR](https://github.com/BridgeAR))
- Twitter: [@BridgeAR](https://twitter.com/BridgeAR)
From caa5ac70982d3cf6747cc74854f07c2f8eb288e2 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 04:55:18 +0000
Subject: [PATCH 70/96] docs & npm ignore
---
.npmignore | 1 +
CONTRIBUTING.md | 51 +++++++++++++++++++++++++------------------------
README.md | 2 +-
3 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/.npmignore b/.npmignore
index 497486e4e0..6e559f54aa 100644
--- a/.npmignore
+++ b/.npmignore
@@ -17,3 +17,4 @@ CODE_OF_CONDUCT.md
.travis.yml
appveyor.yml
package-lock.json
+.prettierrc
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 192219267a..f9cba8b4a6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -13,38 +13,39 @@ We welcome any type of contribution, not just code. You can help with;
## Project Guidelines
-As maintainers of this project, we want to ensure that the project lives and continues to grow. Not blocked by any
+As maintainers of this project, we want to ensure that the project lives and continues to grow. Not blocked by any
singular person's time.
-One of the simplest ways of doing this is by encouraging a larger set of shallow contributors. Through this we hope to
+One of the simplest ways of doing this is by encouraging a larger set of shallow contributors. Through this we hope to
mitigate the problems of a project that needs updates but there is no-one who has the power to do so.
### Continuous Deployment
+
Coming soon.
### How can we help you get comfortable contributing?
-It is normal for a first pull request to be a potential fix for a problem but moving on from there to helping the
+It is normal for a first pull request to be a potential fix for a problem but moving on from there to helping the
project's direction can be difficult.
-We try to help contributors cross that barrier by offering good first step issues (labelled `good-first-issue`). These
-issues can be fixed without feeling like you are stepping on toes. Generally, these should be non-critical issues that
+We try to help contributors cross that barrier by offering good first step issues (labelled `good-first-issue`). These
+issues can be fixed without feeling like you are stepping on toes. Generally, these should be non-critical issues that
are well defined. They will be purposely avoided by mature contributors to the project, to make space for others.
-Additionally issues labelled `needs-triage` or `help-wanted` can also be picked up, these may not necessarily require
-code changes but rather help with debugging and finding the cause of the issue whether it's a bug or a users incorrect
+Additionally issues labelled `needs-triage` or `help-wanted` can also be picked up, these may not necessarily require
+code changes but rather help with debugging and finding the cause of the issue whether it's a bug or a users incorrect
setup of the library or project.
-We aim to keep all project discussion inside GitHub issues. This is to make sure valuable discussion is accessible via
-search. If you have questions about how to use the library, or how the project is running - GitHub issues are the goto
+We aim to keep all project discussion inside GitHub issues. This is to make sure valuable discussion is accessible via
+search. If you have questions about how to use the library, or how the project is running - GitHub issues are the goto
tool for this project.
### Our expectations on you as a contributor
-You shouldn't feel bad for not contributing to open source. We want contributors like yourself to provide ideas, keep
-the ship shipping and to take some of the load from others. It is non-obligatory; we’re here to get things done in an
+You shouldn't feel bad for not contributing to open source. We want contributors like yourself to provide ideas, keep
+the ship shipping and to take some of the load from others. It is non-obligatory; we’re here to get things done in an
enjoyable way. :trophy:
We only ask that you follow the conduct guidelines set out in our [Code of Conduct](/CODE_OF_CONDUCT.md) throughout your
@@ -52,20 +53,20 @@ contribution journey.
### What about if you have problems that cannot be discussed in public?
-You can reach out to us directly via email (`redis[AT]invertase.io`) or direct message us on
+You can reach out to us directly via email (`redis[AT]invertase.io`) or direct message us on
[Twitter](https://twitter.com/NodeRedis) if you'd like to discuss something privately.
#### Project Maintainers
- - Mike Diarmid ([Salakar](https://github.com/Salakar)) @ [Invertase](https://github.com/invertase)
- - Twitter: [@mikediarmid](https://twitter.com/mikediarmid)
- - Elliot Hesp ([Ehesp](https://github.com/Ehesp)) @ [Invertase](https://github.com/invertase)
- - Twitter: [@elliothesp](https://twitter.com/elliothesp)
- - Ruben Bridgewater ([BridgeAR](https://github.com/BridgeAR))
- - Twitter: [@BridgeAR](https://twitter.com/BridgeAR)
-
-Huge thanks to the original author of Node Redis, [Matthew Ranney](https://github.com/mranney) and also to
-[Ruben Bridgewater](https://github.com/BridgeAR) for handing over this project over to new maintainers so it could be
+- Mike Diarmid ([Salakar](https://github.com/Salakar)) @ [Invertase](https://github.com/invertase)
+ - Twitter: [@mikediarmid](https://twitter.com/mikediarmid)
+- Elliot Hesp ([Ehesp](https://github.com/Ehesp)) @ [Invertase](https://github.com/invertase)
+ - Twitter: [@elliothesp](https://twitter.com/elliothesp)
+- Ruben Bridgewater ([BridgeAR](https://github.com/BridgeAR))
+ - Twitter: [@BridgeAR](https://twitter.com/BridgeAR)
+
+Huge thanks to the original author of Node Redis, [Matthew Ranney](https://github.com/mranney) and also to
+[Ruben Bridgewater](https://github.com/BridgeAR) for handing over this project over to new maintainers so it could be
continuously maintained.
---
@@ -74,7 +75,7 @@ continuously maintained.
### Your First Contribution
-Working on your first Pull Request? You can learn how from this _free_ series,
+Working on your first Pull Request? You can learn how from this _free_ series,
[How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github).
### Testing Code
@@ -86,8 +87,8 @@ testing and open the generated `./coverage/index.html` in your browser.
### Submitting code for review
-The bigger the pull request, the longer it will take to review and merge. Where possible try to break down large pull
-requests into smaller chunks that are easier to review and merge. It is also always helpful to have some context for
+The bigger the pull request, the longer it will take to review and merge. Where possible try to break down large pull
+requests into smaller chunks that are easier to review and merge. It is also always helpful to have some context for
your pull request. What was the purpose? Why does it matter to you? What problem are you trying to solve? Tag in any linked issues.
To aid review we also ask that you fill out the pull request template as much as possible.
@@ -96,7 +97,7 @@ To aid review we also ask that you fill out the pull request template as much as
### Code review process
-Pull Requests to the protected branches require two or more peer-review approvals and passing status checks to be able
+Pull Requests to the protected branches require two or more peer-review approvals and passing status checks to be able
to be merged.
When reviewing a Pull Request please check the following steps on top of the existing automated checks:
diff --git a/README.md b/README.md
index 236a214b5c..abc9afdbee 100644
--- a/README.md
+++ b/README.md
@@ -971,7 +971,7 @@ Good stack traces are only activated in development and debug mode as this
results in a significant performance penalty.
**_Comparison_**:
-
+
Standard stack trace:
```
From 5b94673fb691f48076af5c76b71bf038a48ba3cf Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 04:59:59 +0000
Subject: [PATCH 71/96] docs
---
README.md | 34 ++++++++++++++++------------------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/README.md b/README.md
index abc9afdbee..847dd8bd20 100644
--- a/README.md
+++ b/README.md
@@ -11,9 +11,9 @@
-
+
-
+
@@ -131,11 +131,11 @@ after losing the connection. Listeners are passed an object containing `delay`
#### `"error"`
`client` will emit `error` when encountering an error connecting to the Redis
-server or when any other in node_redis occurs. If you use a command without
+server or when any other in Node Redis occurs. If you use a command without
callback and encounter a ReplyError it is going to be emitted to the error
listener.
-So please attach the error listener to node_redis.
+So please attach the error listener to Node Redis.
#### `"end"`
@@ -171,15 +171,15 @@ using unix sockets if possible to increase throughput.
| port | 6379 | Port of the Redis server |
| path | null | The UNIX socket string of the Redis server |
| url | null | The URL of the Redis server. Format: `[redis[s]:]//[[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)). |
-| 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. |
+| 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. |
| return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. |
| 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. |
| socket_keepalive | true | If set to `true`, the keep-alive functionality is enabled on the underlying socket. |
| socket_initial_delay | 0 | Initial Delay in milliseconds, and this will also behave the interval keep alive message sending to Redis. |
-| no_ready_check | false | When a connection is established to the Redis server, the server might still be loading the database from disk. While loading, the server will not respond to any commands. To work around this, `node_redis` has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command indicates whether the server is ready for more commands. When ready, `node_redis` emits a `ready` event. Setting `no_ready_check` to `true` will inhibit this check. |
+| no_ready_check | false | When a connection is established to the Redis server, the server might still be loading the database from disk. While loading, the server will not respond to any commands. To work around this, Node Redis has a "ready check" which sends the `INFO` command to the server. The response from the `INFO` command indicates whether the server is ready for more commands. When ready, `node_redis` emits a `ready` event. Setting `no_ready_check` to `true` will inhibit this check. |
| enable_offline_queue | true | By default, if there is no active connection to the Redis server, commands are added to a queue and are executed once the connection has been established. Setting `enable_offline_queue` to `false` will disable this feature and the callback will be executed immediately with an error, or an error will be emitted if no callback is specified. |
| retry_unfulfilled_commands | false | If set to `true`, all commands that were unfulfilled while the connection is lost will be retried after the connection has been reestablished. Use this with caution if you use state altering commands (e.g. `incr`). This is especially useful if you use blocking commands. |
-| password | null | If set, client will run Redis auth command on connect. Alias `auth_pass` **Note** `node_redis` < 2.5 must use `auth_pass` |
+| password | null | If set, client will run Redis auth command on connect. Alias `auth_pass` **Note** Node Redis < 2.5 must use `auth_pass` |
| db | null | If set, client will run Redis `select` command on connect. |
| family | IPv4 | You can force using IPv6 if you set the family to 'IPv6'. See Node.js [net](https://nodejs.org/api/net.html) or [dns](https://nodejs.org/api/dns.html) modules on how to use the family type. |
| disable_resubscribing | false | If set to `true`, a client won't resubscribe after disconnecting. |
@@ -342,14 +342,14 @@ client.set("foo", "bar", "baz", function(err, res) {
Every `ReplyError` contains the `command` name in all-caps and the arguments (`args`).
-If node_redis emits a library error because of another error, the triggering
+If Node Redis emits a library error because of another error, the triggering
error is added to the returned error as `origin` attribute.
**_Error codes_**
-node_redis returns a `NR_CLOSED` error code if the clients connection dropped.
+Node Redis returns a `NR_CLOSED` error code if the clients connection dropped.
If a command unresolved command got rejected a `UNCERTAIN_STATE` code is
-returned. A `CONNECTION_BROKEN` error code is used in case node_redis gives up
+returned. A `CONNECTION_BROKEN` error code is used in case Node Redis gives up
to reconnect.
### client.unref()
@@ -386,9 +386,8 @@ dealing with hash values, there are a couple of useful exceptions to this.
#### client.hgetall(hash, callback)
-The reply from an `HGETALL` command will be converted into a JavaScript Object by
-`node_redis`. That way you can interact with the responses using JavaScript
-syntax.
+The reply from an `HGETALL` command will be converted into a JavaScript Object. That way you can interact with the
+responses using JavaScript syntax.
**Example:**
@@ -514,7 +513,7 @@ left subscriber mode and no more subscriber events will be emitted.
### client.multi([commands])
`MULTI` commands are queued up until an `EXEC` is issued, and then all commands
-are run atomically by Redis. The interface in `node_redis` is to return an
+are run atomically by Redis. The interface returns an
individual `Multi` object by calling `client.multi()`. If any command fails to
queue, all commands are rolled back and none is going to be executed (For
further information see the [Redis transactions](http://redis.io/topics/transactions) documentation).
@@ -743,7 +742,7 @@ Identical to `.multi()` without transactions. This is recommended if you want to
execute many commands at once but don't need to rely on transactions.
`BATCH` commands are queued up until an `EXEC` is issued, and then all commands
-are run atomically by Redis. The interface in `node_redis` is to return an
+are run atomically by Redis. The interface returns an
individual `Batch` object by calling `client.batch()`. The only difference
between .batch and .multi is that no transaction is going to be used.
Be aware that the errors are - just like in multi statements - in the result.
@@ -916,8 +915,7 @@ client.zadd(args, function(addError, addResponse) {
## Performance
-Much effort has been spent to make `node_redis` as fast as possible for common
-operations.
+Much effort has been spent to make Node Redis as fast as possible for common operations.
```
Mac mini (2018), i7-3.2GHz and 32gb memory
@@ -960,7 +958,7 @@ clients: 1, NodeJS: 12.15.0, Redis: 5.0.6, parser: javascript, connected by: tcp
## Debugging
-To get debug output run your `node_redis` application with `NODE_DEBUG=redis`.
+To get debug output run your Node Redis application with `NODE_DEBUG=redis`.
This is also going to result in good stack traces opposed to useless ones
otherwise for any async operation.
From d7470f257af1a6aac85d6bb51171b4dbc4f68cc5 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 05:26:34 +0000
Subject: [PATCH 72/96] docs: issue template formatting
---
.github/ISSUE_TEMPLATE.md | 2 +-
.github/PULL_REQUEST_TEMPLATE.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 42f2d3eeb6..c398d32c37 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -12,4 +12,4 @@ Thank you!_
* **Platform**: What platform / version? (For example Node.js 0.10 or Node.js 5.7.0 on Windows 7 / Ubuntu 15.10 / Azure)
* **Description**: Description of your issue, stack traces from errors and code that reproduces the issue
-[gitter]: https://gitter.im/NodeRedis/node_redis?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
\ No newline at end of file
+[gitter]: https://gitter.im/NodeRedis/node_redis?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 9706621c1b..31dc37c872 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -11,4 +11,4 @@ afterwards / while the PR is open._
### Description of change
-_Please provide a description of the change here._
\ No newline at end of file
+_Please provide a description of the change here._
From e0fddd4deac3a626703b7c7770814baf3ad00e5b Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 05:34:48 +0000
Subject: [PATCH 73/96] chore: add IDE files to .npmignore
---
.npmignore | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.npmignore b/.npmignore
index 6e559f54aa..262ee0c0b4 100644
--- a/.npmignore
+++ b/.npmignore
@@ -11,7 +11,8 @@ coverage/
*.rdb
*.out
*.yml
-CHANGELOG.md
+.vscode
+.idea
CONTRIBUTING.md
CODE_OF_CONDUCT.md
.travis.yml
From 59817914cdad782a220239bcaa99840b5f155680 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 05:42:37 +0000
Subject: [PATCH 74/96] chore: formatting
---
.travis.yml | 3 +++
CODE_OF_CONDUCT.md | 28 +++++++++++++++++++++-------
appveyor.yml | 2 +-
3 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 74f406b15f..7ff40c58a5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,13 +1,16 @@
language: node_js
sudo: required
+
env:
- CXX=g++-4.8 TRAVIS=true
+
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
+
node_js:
- "6"
- "8"
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 50b0a74108..2adee6acb3 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -2,7 +2,10 @@
## Our Pledge
-In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making
+participation in our project and our community a harassment-free experience for everyone, regardless of age, body size,
+disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race,
+religion, or sexual identity and orientation.
## Our Standards
@@ -24,23 +27,34 @@ Examples of unacceptable behavior by participants include:
## Our Responsibilities
-Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take
+appropriate and fair corrective action in response to any instances of unacceptable behavior.
-Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits,
+ issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any
+ contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
-This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the
+project or its community. Examples of representing a project or community include using an official project e-mail address,
+posting via an official social media account, or acting as an appointed representative at an online or offline event.
+Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
-Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at `redis @ invertase.io`. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at
+`redis[AT]invertase.io`. The project team will review and investigate all complaints, and will respond in a way that it
+deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the
+reporter of an incident. Further details of specific enforcement policies may be posted separately.
-Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent
+repercussions as determined by other members of the project's leadership.
## Attribution
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at
+[http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
diff --git a/appveyor.yml b/appveyor.yml
index f8c16e9a4d..a67e581b33 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -17,7 +17,7 @@ shallow_clone: true
# Install scripts. (runs after repo cloning)
install:
- # Install the Redis
+ # Install Redis
- nuget install redis-64 -excludeversion
- redis-64\tools\redis-server.exe --service-install
- redis-64\tools\redis-server.exe --service-start
From 9d68ae76cd4d5d07be4f18f5c8c51054554b7d2b Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 05:44:10 +0000
Subject: [PATCH 75/96] chore: update license
---
LICENSE | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/LICENSE b/LICENSE
index 7b7ba1393b..db86cc4de7 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) Node Redis contributors.
+Copyright (c) 2016-present Node Redis contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
From a513c8b7e221667801faa070de3323c5d21db2b0 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 05:48:50 +0000
Subject: [PATCH 76/96] docs: update readme
---
README.md | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index 847dd8bd20..0167d5dbd0 100644
--- a/README.md
+++ b/README.md
@@ -210,7 +210,7 @@ client.get(new Buffer("foo_rand000000000000"), function(err, reply) {
**`retry_strategy` example:**
```js
-var client = redis.createClient({
+const client = redis.createClient({
retry_strategy: function(options) {
if (options.error && options.error.code === "ECONNREFUSED") {
// End reconnecting on a specific error and flush all commands with
@@ -678,9 +678,9 @@ clients.watcher.watch("foo", function(watchError) {
if (setError) throw err;
});
- //using a setTimeout here to ensure that the MULTI/EXEC will come after the SET.
- //Normally, you would use a callback to ensure order, but I want the above SET command
- //to be easily comment-out-able.
+ // using a setTimeout here to ensure that the MULTI/EXEC will come after the SET.
+ // Normally, you would use a callback to ensure order, but I want the above SET command
+ // to be easily comment-out-able.
setTimeout(function() {
clients.watcher
.multi()
@@ -840,7 +840,7 @@ returns it in the callback. If an error occurs in the meanwhile, that is going
to return an error instead in the callback.
One example of when to use duplicate() would be to accommodate the connection-
-blocking redis commands BRPOP, BLPOP, and BRPOPLPUSH. If these commands
+blocking redis commands `BRPOP`, `BLPOP`, and `BRPOPLPUSH`. If these commands
are used on the same Redis client instance as non-blocking commands, the
non-blocking ones may be queued up until after the blocking ones finish.
From 79927c56a0e2fb7819afbb0e13c6078d0015564e Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 06:08:30 +0000
Subject: [PATCH 77/96] tests: remove unused `parser` client option from all
tests & helpers
---
test/auth.spec.js | 19 +++++++++----------
test/batch.spec.js | 4 ++--
test/commands/blpop.spec.js | 4 ++--
test/commands/client.spec.js | 4 ++--
test/commands/dbsize.spec.js | 4 ++--
test/commands/del.spec.js | 4 ++--
test/commands/eval.spec.js | 4 ++--
test/commands/exists.spec.js | 4 ++--
test/commands/expire.spec.js | 4 ++--
test/commands/flushdb.spec.js | 4 ++--
test/commands/geoadd.spec.js | 4 ++--
test/commands/get.spec.js | 4 ++--
test/commands/getset.spec.js | 4 ++--
test/commands/hgetall.spec.js | 6 +++---
test/commands/hincrby.spec.js | 4 ++--
test/commands/hlen.spec.js | 4 ++--
test/commands/hmget.spec.js | 4 ++--
test/commands/hmset.spec.js | 4 ++--
test/commands/hset.spec.js | 4 ++--
test/commands/incr.spec.js | 4 ++--
test/commands/info.spec.js | 4 ++--
test/commands/keys.spec.js | 4 ++--
test/commands/mget.spec.js | 4 ++--
test/commands/monitor.spec.js | 4 ++--
test/commands/mset.spec.js | 4 ++--
test/commands/msetnx.spec.js | 4 ++--
test/commands/randomkey.test.js | 4 ++--
test/commands/rename.spec.js | 4 ++--
test/commands/renamenx.spec.js | 4 ++--
test/commands/rpush.spec.js | 4 ++--
test/commands/sadd.spec.js | 4 ++--
test/commands/scard.spec.js | 4 ++--
test/commands/script.spec.js | 4 ++--
test/commands/sdiff.spec.js | 4 ++--
test/commands/sdiffstore.spec.js | 4 ++--
test/commands/select.spec.js | 4 ++--
test/commands/set.spec.js | 4 ++--
test/commands/setex.spec.js | 4 ++--
test/commands/setnx.spec.js | 4 ++--
test/commands/sinter.spec.js | 4 ++--
test/commands/sinterstore.spec.js | 4 ++--
test/commands/sismember.spec.js | 4 ++--
test/commands/slowlog.spec.js | 4 ++--
test/commands/smembers.spec.js | 4 ++--
test/commands/smove.spec.js | 4 ++--
test/commands/sort.spec.js | 4 ++--
test/commands/spop.spec.js | 4 ++--
test/commands/srem.spec.js | 4 ++--
test/commands/sunion.spec.js | 4 ++--
test/commands/sunionstore.spec.js | 4 ++--
test/commands/ttl.spec.js | 4 ++--
test/commands/type.spec.js | 4 ++--
test/commands/watch.spec.js | 4 ++--
test/commands/zadd.spec.js | 4 ++--
test/commands/zscan.spec.js | 4 ++--
test/commands/zscore.spec.js | 4 ++--
test/connection.spec.js | 19 ++++++-------------
test/detect_buffers.spec.js | 2 +-
test/helper.js | 13 +++++--------
test/lib/config.js | 4 +---
test/multi.spec.js | 4 ++--
test/node_redis.spec.js | 15 ++++-----------
test/prefix.spec.js | 5 ++---
test/pubsub.spec.js | 4 ++--
test/rename.spec.js | 6 ++----
test/return_buffers.spec.js | 8 ++++----
66 files changed, 149 insertions(+), 172 deletions(-)
diff --git a/test/auth.spec.js b/test/auth.spec.js
index 67e6d0924a..d88ac6304e 100644
--- a/test/auth.spec.js
+++ b/test/auth.spec.js
@@ -19,9 +19,9 @@ describe('client authentication', function () {
helper.allTests({
allConnections: true
- }, function (parser, ip, args) {
+ }, function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var auth = 'porkchopsandwiches';
var client = null;
@@ -133,7 +133,7 @@ describe('client authentication', function () {
it('allows auth to be provided as config option for client', function (done) {
if (helper.redisProcess().spawnFailed()) this.skip();
- var args = config.configureClient(parser, ip, {
+ var args = config.configureClient(ip, {
auth_pass: auth
});
client = redis.createClient.apply(null, args);
@@ -143,7 +143,7 @@ describe('client authentication', function () {
it('allows auth and no_ready_check to be provided as config option for client', function (done) {
if (helper.redisProcess().spawnFailed()) this.skip();
- var args = config.configureClient(parser, ip, {
+ var args = config.configureClient(ip, {
password: auth,
no_ready_check: true
});
@@ -154,7 +154,7 @@ describe('client authentication', function () {
it('allows auth to be provided post-hoc with auth method', function (done) {
if (helper.redisProcess().spawnFailed()) this.skip();
- var args = config.configureClient(parser, ip);
+ var args = config.configureClient(ip);
client = redis.createClient.apply(null, args);
client.auth(auth);
client.on('ready', done);
@@ -217,7 +217,7 @@ describe('client authentication', function () {
it('allows auth to be provided post-hoc with auth method again', function (done) {
if (helper.redisProcess().spawnFailed()) this.skip();
- var args = config.configureClient(parser, ip, {
+ var args = config.configureClient(ip, {
auth_pass: auth
});
client = redis.createClient.apply(null, args);
@@ -229,7 +229,7 @@ describe('client authentication', function () {
it('does not allow any commands to be processed if not authenticated using no_ready_check true', function (done) {
if (helper.redisProcess().spawnFailed()) this.skip();
- var args = config.configureClient(parser, ip, {
+ var args = config.configureClient(ip, {
no_ready_check: true
});
client = redis.createClient.apply(null, args);
@@ -258,7 +258,6 @@ describe('client authentication', function () {
if (helper.redisProcess().spawnFailed()) this.skip();
client = redis.createClient({
password: 'wrong_password',
- parser: parser
});
client.once('error', function (err) {
assert.strictEqual(err.message, 'ERR invalid password');
@@ -269,7 +268,7 @@ describe('client authentication', function () {
it('pubsub working with auth', function (done) {
if (helper.redisProcess().spawnFailed()) this.skip();
- var args = config.configureClient(parser, ip, {
+ var args = config.configureClient(ip, {
password: auth
});
client = redis.createClient.apply(null, args);
@@ -299,7 +298,7 @@ describe('client authentication', function () {
// returning the manipulated [error, result] from the callback.
// There should be a better solution though
- var args = config.configureClient(parser, 'localhost', {
+ var args = config.configureClient('localhost', {
noReadyCheck: true
});
client = redis.createClient.apply(null, args);
diff --git a/test/batch.spec.js b/test/batch.spec.js
index df038e77e6..05cee80681 100644
--- a/test/batch.spec.js
+++ b/test/batch.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'batch' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
describe('when not connected', function () {
var client;
diff --git a/test/commands/blpop.spec.js b/test/commands/blpop.spec.js
index e8d3f59aab..64aedf81ea 100644
--- a/test/commands/blpop.spec.js
+++ b/test/commands/blpop.spec.js
@@ -8,9 +8,9 @@ var intercept = require('intercept-stdout');
describe("The 'blpop' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
var bclient;
diff --git a/test/commands/client.spec.js b/test/commands/client.spec.js
index 7ac32ae41a..51a55e3f16 100644
--- a/test/commands/client.spec.js
+++ b/test/commands/client.spec.js
@@ -7,10 +7,10 @@ var redis = config.redis;
describe("The 'client' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
var pattern = /addr=/;
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/dbsize.spec.js b/test/commands/dbsize.spec.js
index 4fdf80010d..bd8b146789 100644
--- a/test/commands/dbsize.spec.js
+++ b/test/commands/dbsize.spec.js
@@ -8,9 +8,9 @@ var uuid = require('uuid');
describe("The 'dbsize' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var key, value;
beforeEach(function () {
diff --git a/test/commands/del.spec.js b/test/commands/del.spec.js
index 970d0886c4..86c1f4bb3a 100644
--- a/test/commands/del.spec.js
+++ b/test/commands/del.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'del' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/eval.spec.js b/test/commands/eval.spec.js
index 731d656d54..db74372db4 100644
--- a/test/commands/eval.spec.js
+++ b/test/commands/eval.spec.js
@@ -8,9 +8,9 @@ var redis = config.redis;
describe("The 'eval' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
var source = "return redis.call('set', 'sha', 'test')";
diff --git a/test/commands/exists.spec.js b/test/commands/exists.spec.js
index 01a1b6891d..399a0382f4 100644
--- a/test/commands/exists.spec.js
+++ b/test/commands/exists.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'exists' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/expire.spec.js b/test/commands/expire.spec.js
index f9041b7109..2891890edc 100644
--- a/test/commands/expire.spec.js
+++ b/test/commands/expire.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'expire' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/flushdb.spec.js b/test/commands/flushdb.spec.js
index 61535e2e71..a4f761d375 100644
--- a/test/commands/flushdb.spec.js
+++ b/test/commands/flushdb.spec.js
@@ -8,9 +8,9 @@ var uuid = require('uuid');
describe("The 'flushdb' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var key, key2;
beforeEach(function () {
diff --git a/test/commands/geoadd.spec.js b/test/commands/geoadd.spec.js
index 3614910322..b45df7c83a 100644
--- a/test/commands/geoadd.spec.js
+++ b/test/commands/geoadd.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'geoadd' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/get.spec.js b/test/commands/get.spec.js
index e2b9a7db07..acbfc0d10d 100644
--- a/test/commands/get.spec.js
+++ b/test/commands/get.spec.js
@@ -8,9 +8,9 @@ var uuid = require('uuid');
describe("The 'get' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var key, value;
beforeEach(function () {
diff --git a/test/commands/getset.spec.js b/test/commands/getset.spec.js
index e5da857311..48dd7e9d73 100644
--- a/test/commands/getset.spec.js
+++ b/test/commands/getset.spec.js
@@ -8,9 +8,9 @@ var uuid = require('uuid');
describe("The 'getset' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var key, value, value2;
beforeEach(function () {
diff --git a/test/commands/hgetall.spec.js b/test/commands/hgetall.spec.js
index 6c00e3ed09..b74995427a 100644
--- a/test/commands/hgetall.spec.js
+++ b/test/commands/hgetall.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'hgetall' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
describe('regular client', function () {
@@ -51,7 +51,7 @@ describe("The 'hgetall' method", function () {
describe('binary client', function () {
var client;
- var args = config.configureClient(parser, ip, {
+ var args = config.configureClient(ip, {
return_buffers: true
});
diff --git a/test/commands/hincrby.spec.js b/test/commands/hincrby.spec.js
index e94232d9a0..10b4523b3f 100644
--- a/test/commands/hincrby.spec.js
+++ b/test/commands/hincrby.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'hincrby' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
var hash = 'test hash';
diff --git a/test/commands/hlen.spec.js b/test/commands/hlen.spec.js
index 5dcab6ce8e..f1f94fec02 100644
--- a/test/commands/hlen.spec.js
+++ b/test/commands/hlen.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'hlen' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/hmget.spec.js b/test/commands/hmget.spec.js
index 09bb89f258..3676b5b731 100644
--- a/test/commands/hmget.spec.js
+++ b/test/commands/hmget.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'hmget' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
var hash = 'test hash';
diff --git a/test/commands/hmset.spec.js b/test/commands/hmset.spec.js
index 93514cc229..8ba54ecc3f 100644
--- a/test/commands/hmset.spec.js
+++ b/test/commands/hmset.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'hmset' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
var hash = 'test hash';
diff --git a/test/commands/hset.spec.js b/test/commands/hset.spec.js
index c62b17713b..d94a7aa0f2 100644
--- a/test/commands/hset.spec.js
+++ b/test/commands/hset.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'hset' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
var hash = 'test hash';
diff --git a/test/commands/incr.spec.js b/test/commands/incr.spec.js
index f1f1e78ee8..0caab84859 100644
--- a/test/commands/incr.spec.js
+++ b/test/commands/incr.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'incr' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
describe('when connected and a value in Redis', function () {
diff --git a/test/commands/info.spec.js b/test/commands/info.spec.js
index 39a9e9f5cc..4e5bb481fc 100644
--- a/test/commands/info.spec.js
+++ b/test/commands/info.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'info' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/keys.spec.js b/test/commands/keys.spec.js
index 1aff0cea14..6ce45790b6 100644
--- a/test/commands/keys.spec.js
+++ b/test/commands/keys.spec.js
@@ -8,9 +8,9 @@ var redis = config.redis;
describe("The 'keys' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/mget.spec.js b/test/commands/mget.spec.js
index 83d69f837f..a2c671f683 100644
--- a/test/commands/mget.spec.js
+++ b/test/commands/mget.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'mget' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/monitor.spec.js b/test/commands/monitor.spec.js
index a6c9874730..7465ac4eb8 100644
--- a/test/commands/monitor.spec.js
+++ b/test/commands/monitor.spec.js
@@ -8,7 +8,7 @@ var redis = config.redis;
describe("The 'monitor' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
var client;
@@ -62,7 +62,7 @@ describe("The 'monitor' method", function () {
end(err);
});
monitorClient.subscribe('foo', 'baz', function (err, res) {
- // The return value might change in v.3
+ // The return value might change in v.4
// assert.strictEqual(res, 'baz');
// TODO: Fix the return value of subscribe calls
end(err);
diff --git a/test/commands/mset.spec.js b/test/commands/mset.spec.js
index 9fac90728c..b60f383134 100644
--- a/test/commands/mset.spec.js
+++ b/test/commands/mset.spec.js
@@ -8,9 +8,9 @@ var uuid = require('uuid');
describe("The 'mset' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var key, value, key2, value2;
beforeEach(function () {
diff --git a/test/commands/msetnx.spec.js b/test/commands/msetnx.spec.js
index a2f2ab1724..179f33744e 100644
--- a/test/commands/msetnx.spec.js
+++ b/test/commands/msetnx.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'msetnx' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/randomkey.test.js b/test/commands/randomkey.test.js
index cf453e12e4..226194f921 100644
--- a/test/commands/randomkey.test.js
+++ b/test/commands/randomkey.test.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'randomkey' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/rename.spec.js b/test/commands/rename.spec.js
index cb3d7c3168..284fba310e 100644
--- a/test/commands/rename.spec.js
+++ b/test/commands/rename.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'rename' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/renamenx.spec.js b/test/commands/renamenx.spec.js
index 3da640a0d8..b56b0a1a5c 100644
--- a/test/commands/renamenx.spec.js
+++ b/test/commands/renamenx.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'renamenx' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/rpush.spec.js b/test/commands/rpush.spec.js
index d137dc6473..793d5d2d80 100644
--- a/test/commands/rpush.spec.js
+++ b/test/commands/rpush.spec.js
@@ -7,9 +7,9 @@ var assert = require('assert');
describe("The 'rpush' command", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/sadd.spec.js b/test/commands/sadd.spec.js
index c2316739b7..442f391b9d 100644
--- a/test/commands/sadd.spec.js
+++ b/test/commands/sadd.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'sadd' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/scard.spec.js b/test/commands/scard.spec.js
index 5cf9b4eb73..e327eb282a 100644
--- a/test/commands/scard.spec.js
+++ b/test/commands/scard.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'scard' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/script.spec.js b/test/commands/script.spec.js
index 2e29ad553a..c374f5b5e1 100644
--- a/test/commands/script.spec.js
+++ b/test/commands/script.spec.js
@@ -8,11 +8,11 @@ var redis = config.redis;
describe("The 'script' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
var command = 'return 99';
var commandSha = crypto.createHash('sha1').update(command).digest('hex');
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/sdiff.spec.js b/test/commands/sdiff.spec.js
index e3963ecdf0..95f81f09bd 100644
--- a/test/commands/sdiff.spec.js
+++ b/test/commands/sdiff.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'sdiff' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/sdiffstore.spec.js b/test/commands/sdiffstore.spec.js
index 1797ca9e43..fe822b561b 100644
--- a/test/commands/sdiffstore.spec.js
+++ b/test/commands/sdiffstore.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'sdiffstore' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/select.spec.js b/test/commands/select.spec.js
index 66a66f389b..053496e337 100644
--- a/test/commands/select.spec.js
+++ b/test/commands/select.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'select' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
describe('when not connected', function () {
var client;
diff --git a/test/commands/set.spec.js b/test/commands/set.spec.js
index 360cffe5f5..d2d36491a9 100644
--- a/test/commands/set.spec.js
+++ b/test/commands/set.spec.js
@@ -8,9 +8,9 @@ var uuid = require('uuid');
describe("The 'set' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var key, value;
beforeEach(function () {
diff --git a/test/commands/setex.spec.js b/test/commands/setex.spec.js
index 9a3bb53f0b..a2126e6dbb 100644
--- a/test/commands/setex.spec.js
+++ b/test/commands/setex.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'setex' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/setnx.spec.js b/test/commands/setnx.spec.js
index 2bce9f0a0b..4b4688c0a6 100644
--- a/test/commands/setnx.spec.js
+++ b/test/commands/setnx.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'setnx' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/sinter.spec.js b/test/commands/sinter.spec.js
index b614a41ea4..c4fc775955 100644
--- a/test/commands/sinter.spec.js
+++ b/test/commands/sinter.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'sinter' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/sinterstore.spec.js b/test/commands/sinterstore.spec.js
index de7de87e10..1ea4c4b109 100644
--- a/test/commands/sinterstore.spec.js
+++ b/test/commands/sinterstore.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'sinterstore' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/sismember.spec.js b/test/commands/sismember.spec.js
index 69482b3b56..37ac1c466a 100644
--- a/test/commands/sismember.spec.js
+++ b/test/commands/sismember.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'sismember' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/slowlog.spec.js b/test/commands/slowlog.spec.js
index 7f5417dbd8..21f3f8007a 100644
--- a/test/commands/slowlog.spec.js
+++ b/test/commands/slowlog.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'slowlog' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/smembers.spec.js b/test/commands/smembers.spec.js
index 8fbdcbba5e..0bc8143719 100644
--- a/test/commands/smembers.spec.js
+++ b/test/commands/smembers.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'smembers' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/smove.spec.js b/test/commands/smove.spec.js
index eb8eae1054..969c264b75 100644
--- a/test/commands/smove.spec.js
+++ b/test/commands/smove.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'smove' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/sort.spec.js b/test/commands/sort.spec.js
index 63b933eaef..2ee08c44e2 100644
--- a/test/commands/sort.spec.js
+++ b/test/commands/sort.spec.js
@@ -34,9 +34,9 @@ function setupData (client, done) {
describe("The 'sort' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/spop.spec.js b/test/commands/spop.spec.js
index 6e0697c02a..ec3e93fda3 100644
--- a/test/commands/spop.spec.js
+++ b/test/commands/spop.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'spop' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/srem.spec.js b/test/commands/srem.spec.js
index 97c40d9ce2..d325cb5715 100644
--- a/test/commands/srem.spec.js
+++ b/test/commands/srem.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'srem' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/sunion.spec.js b/test/commands/sunion.spec.js
index 44f5f24720..cc8eb62475 100644
--- a/test/commands/sunion.spec.js
+++ b/test/commands/sunion.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'sunion' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/sunionstore.spec.js b/test/commands/sunionstore.spec.js
index c9869bdf88..bd64c6f6b7 100644
--- a/test/commands/sunionstore.spec.js
+++ b/test/commands/sunionstore.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'sunionstore' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/ttl.spec.js b/test/commands/ttl.spec.js
index 65212f710c..e176d41cb8 100644
--- a/test/commands/ttl.spec.js
+++ b/test/commands/ttl.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'ttl' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/type.spec.js b/test/commands/type.spec.js
index 4a0c4d2897..f70d79e9ef 100644
--- a/test/commands/type.spec.js
+++ b/test/commands/type.spec.js
@@ -6,9 +6,9 @@ var redis = config.redis;
describe("The 'type' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/watch.spec.js b/test/commands/watch.spec.js
index cf90864675..52a9b26f75 100644
--- a/test/commands/watch.spec.js
+++ b/test/commands/watch.spec.js
@@ -7,11 +7,11 @@ var redis = config.redis;
describe("The 'watch' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
var watched = 'foobar';
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/zadd.spec.js b/test/commands/zadd.spec.js
index e0153ba11b..827630a389 100644
--- a/test/commands/zadd.spec.js
+++ b/test/commands/zadd.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'zadd' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/zscan.spec.js b/test/commands/zscan.spec.js
index 6d4a1a60c8..eb8acf44db 100644
--- a/test/commands/zscan.spec.js
+++ b/test/commands/zscan.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'zscan' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/commands/zscore.spec.js b/test/commands/zscore.spec.js
index 9d24d7a7cf..8b95e52764 100644
--- a/test/commands/zscore.spec.js
+++ b/test/commands/zscore.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe("The 'zscore' method", function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
beforeEach(function (done) {
diff --git a/test/connection.spec.js b/test/connection.spec.js
index 7ecee69853..0913a26ff6 100644
--- a/test/connection.spec.js
+++ b/test/connection.spec.js
@@ -147,9 +147,9 @@ describe('connection tests', function () {
});
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
describe('on lost connection', function () {
it('emit an error after max retry timeout and do not try to reconnect afterwards', function (done) {
@@ -158,7 +158,6 @@ describe('connection tests', function () {
var connect_timeout = 600; // in ms
client = redis.createClient({
- parser: parser,
connect_timeout: connect_timeout
});
var time = 0;
@@ -189,7 +188,6 @@ describe('connection tests', function () {
it('end connection while retry is still ongoing', function (done) {
var connect_timeout = 1000; // in ms
client = redis.createClient({
- parser: parser,
connect_timeout: connect_timeout
});
@@ -304,7 +302,6 @@ describe('connection tests', function () {
it('emit an error after the socket timeout exceeded the connect_timeout time', function (done) {
var connect_timeout = 500; // in ms
client = redis.createClient({
- parser: parser,
// Auto detect ipv4 and use non routable ip to trigger the timeout
host: '10.255.255.1',
connect_timeout: connect_timeout
@@ -337,7 +334,6 @@ describe('connection tests', function () {
it('use the system socket timeout if the connect_timeout has not been provided', function (done) {
client = redis.createClient({
- parser: parser,
host: '2001:db8::ff00:42:8329' // auto detect ip v6
});
assert.strictEqual(client.address, '2001:db8::ff00:42:8329:6379');
@@ -350,21 +346,20 @@ describe('connection tests', function () {
it('clears the socket timeout after a connection has been established', function (done) {
client = redis.createClient({
- parser: parser,
connect_timeout: 1000
});
process.nextTick(function () {
- // node > 4
+ // node > 6
var timeout = client.stream.timeout;
- // node <= 4
+ // node <= 6
if (timeout === undefined) timeout = client.stream._idleTimeout;
assert.strictEqual(timeout, 1000);
});
client.on('connect', function () {
- // node > 4
+ // node > 6
var expected = 0;
var timeout = client.stream.timeout;
- // node <= 4
+ // node <= 6
if (timeout === undefined) {
timeout = client.stream._idleTimeout;
expected = -1;
@@ -379,7 +374,6 @@ describe('connection tests', function () {
client = redis.createClient({
host: 'localhost',
port: '6379',
- parser: parser,
connect_timeout: 1000
});
@@ -392,7 +386,6 @@ describe('connection tests', function () {
}
client = redis.createClient({
path: '/tmp/redis.sock',
- parser: parser,
connect_timeout: 1000
});
diff --git a/test/detect_buffers.spec.js b/test/detect_buffers.spec.js
index 2e2f7f1ed0..a656c54943 100644
--- a/test/detect_buffers.spec.js
+++ b/test/detect_buffers.spec.js
@@ -8,7 +8,7 @@ var redis = config.redis;
describe('detect_buffers', function () {
var client;
- var args = config.configureClient('javascript', 'localhost', {
+ var args = config.configureClient('localhost', {
detect_buffers: true
});
diff --git a/test/helper.js b/test/helper.js
index 29a07d6f31..3e1437d14a 100644
--- a/test/helper.js
+++ b/test/helper.js
@@ -161,7 +161,6 @@ module.exports = {
cb = opts;
opts = {};
}
- var parsers = ['javascript'];
var protocols = ['IPv4'];
if (process.platform !== 'win32') {
protocols.push('IPv6', '/tmp/redis.sock');
@@ -180,13 +179,11 @@ module.exports = {
}
}
describe('using options: ' + strOptions, function () {
- parsers.forEach(function (parser) {
- protocols.forEach(function (ip, i) {
- if (i !== 0 && !opts.allConnections) {
- return;
- }
- cb(parser, ip, config.configureClient(parser, ip, options));
- });
+ protocols.forEach(function (ip, i) {
+ if (i !== 0 && !opts.allConnections) {
+ return;
+ }
+ cb(ip, config.configureClient(ip, options));
});
});
});
diff --git a/test/lib/config.js b/test/lib/config.js
index 0420b032ce..d363f83e04 100644
--- a/test/lib/config.js
+++ b/test/lib/config.js
@@ -16,7 +16,7 @@ var config = {
IPv4: '127.0.0.1',
IPv6: '::1'
},
- configureClient: function (parser, ip, opts) {
+ configureClient: function (ip, opts) {
var args = [];
// Do not manipulate the opts => copy them each time
opts = opts ? JSON.parse(JSON.stringify(opts)) : {};
@@ -28,8 +28,6 @@ var config = {
args.push(config.HOST[ip]);
opts.family = ip;
}
-
- opts.parser = parser;
args.push(opts);
return args;
diff --git a/test/multi.spec.js b/test/multi.spec.js
index 233ead776c..498168f9d5 100644
--- a/test/multi.spec.js
+++ b/test/multi.spec.js
@@ -93,9 +93,9 @@ describe("The 'multi' method", function () {
});
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
describe('when not connected', function () {
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index 3c511ec9af..79f58dd518 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -79,9 +79,9 @@ describe('The node_redis client', function () {
client.stream.destroy();
});
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
afterEach(function () {
client.end(true);
@@ -375,7 +375,6 @@ describe('The node_redis client', function () {
it('should retry all commands instead of returning an error if a command did not yet return after a connection loss', function (done) {
var bclient = redis.createClient({
- parser: parser,
retry_unfulfilled_commands: true
});
bclient.blpop('blocking list 2', 5, function (err, value) {
@@ -394,7 +393,6 @@ describe('The node_redis client', function () {
it('should retry all commands even if the offline queue is disabled', function (done) {
var bclient = redis.createClient({
- parser: parser,
enableOfflineQueue: false,
retryUnfulfilledCommands: true
});
@@ -751,7 +749,7 @@ describe('The node_redis client', function () {
});
});
- // TODO: consider allowing loading commands in v.3
+ // TODO: consider allowing loading commands in v.4
// it('should fire early', function (done) {
// client = redis.createClient.apply(null, args);
// var fired = false;
@@ -884,9 +882,7 @@ describe('The node_redis client', function () {
});
it('flushes the command queue if connection is lost', function (done) {
- client = redis.createClient({
- parser: parser
- });
+ client = redis.createClient();
client.once('ready', function () {
var multi = client.multi();
@@ -938,7 +934,6 @@ describe('The node_redis client', function () {
it('stream not writable', function (done) {
client = redis.createClient({
- parser: parser,
enable_offline_queue: false
});
client.on('ready', function () {
@@ -952,7 +947,6 @@ describe('The node_redis client', function () {
it('emit an error and does not enqueues operation', function (done) {
client = redis.createClient(9999, null, {
- parser: parser,
max_attempts: 0,
enable_offline_queue: false
});
@@ -977,7 +971,6 @@ describe('The node_redis client', function () {
it('flushes the command queue if connection is lost', function (done) {
client = redis.createClient({
- parser: parser,
enable_offline_queue: false
});
diff --git a/test/prefix.spec.js b/test/prefix.spec.js
index e34805a7a9..52fd39c1cc 100644
--- a/test/prefix.spec.js
+++ b/test/prefix.spec.js
@@ -7,14 +7,13 @@ var redis = config.redis;
describe('prefix key names', function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client = null;
beforeEach(function (done) {
client = redis.createClient({
- parser: parser,
prefix: 'test:prefix:'
});
client.on('ready', function () {
diff --git a/test/pubsub.spec.js b/test/pubsub.spec.js
index da2561459f..e0c71adf91 100644
--- a/test/pubsub.spec.js
+++ b/test/pubsub.spec.js
@@ -7,9 +7,9 @@ var redis = config.redis;
describe('publish/subscribe', function () {
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var pub = null;
var sub = null;
var channel = 'test channel';
diff --git a/test/rename.spec.js b/test/rename.spec.js
index b8f7c65d0d..f43eee35ca 100644
--- a/test/rename.spec.js
+++ b/test/rename.spec.js
@@ -17,9 +17,9 @@ describe('rename commands', function () {
});
});
- helper.allTests(function (parser, ip, args) {
+ helper.allTests(function (ip, args) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client = null;
beforeEach(function (done) {
@@ -29,7 +29,6 @@ describe('rename commands', function () {
set: '807081f5afa96845a02816a28b7258c3',
GETRANGE: '9e3102b15cf231c4e9e940f284744fe0'
},
- parser: parser
});
client.on('ready', function () {
@@ -124,7 +123,6 @@ describe('rename commands', function () {
rename_commands: {
set: '807081f5afa96845a02816a28b7258c3'
},
- parser: parser,
prefix: 'baz'
});
client.set('foo', 'bar');
diff --git a/test/return_buffers.spec.js b/test/return_buffers.spec.js
index eb18d79393..ba40c26c37 100644
--- a/test/return_buffers.spec.js
+++ b/test/return_buffers.spec.js
@@ -7,11 +7,11 @@ var redis = config.redis;
describe('return_buffers', function () {
- helper.allTests(function (parser, ip, basicArgs) {
+ helper.allTests(function (ip, basicArgs) {
- describe('using ' + parser + ' and ' + ip, function () {
+ describe('using ' + ip, function () {
var client;
- var args = config.configureClient(parser, ip, {
+ var args = config.configureClient(ip, {
return_buffers: true,
detect_buffers: true
});
@@ -243,7 +243,7 @@ describe('return_buffers', function () {
var channel = 'test channel';
var message = new Buffer('test message');
- var args = config.configureClient(parser, ip, {
+ var args = config.configureClient(ip, {
return_buffers: true
});
From 92ea8e65a9fd45ac246e17ccfbbda57838bed83d Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 06:12:51 +0000
Subject: [PATCH 78/96] docs: update changelog
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 49be75d7d1..186da332a4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,6 +28,7 @@ a lot of old deprecated features and old internals in preparation for an upcomin
- Replaced `double-ended-queue` with `denque`, which brings performance improvements
- Add timestamps to debug traces
- Add `socket_initial_delay` option for `socket.setKeepAlive` (#1396)
+- Add support for `rediss` protocol in url (#1282)
## v2.8.0 - 31 Jul, 2017
From 8f727993a736a33c3eefc48fc7ae4bf9bc2e509d Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 12:42:47 +0000
Subject: [PATCH 79/96] chore: release v3.0.1
---
package.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index 1a5752d8c4..e36c892484 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "redis",
- "version": "3.0.0",
+ "version": "3.0.1",
"description": "A high performance Redis client.",
"keywords": [
"database",
@@ -36,7 +36,6 @@
},
"dependencies": {
"denque": "^1.4.1",
- "prettier": "^1.19.1",
"redis-commands": "^1.5.0",
"redis-errors": "^1.2.0",
"redis-parser": "^3.0.0"
@@ -45,6 +44,7 @@
"node": ">=6"
},
"devDependencies": {
+ "prettier": "^1.19.1",
"bluebird": "^3.7.2",
"coveralls": "^2.11.2",
"eslint": "^6.8.0",
From 33363e6a07472704207baba41175e9f8ca68c247 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 13:11:47 +0000
Subject: [PATCH 80/96] chore: configure travis for windows builds
---
.travis.yml | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 7ff40c58a5..473d621827 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,10 @@
language: node_js
sudo: required
+os:
+ - windows
+ - linux
+
env:
- CXX=g++-4.8 TRAVIS=true
@@ -11,6 +15,7 @@ addons:
packages:
- g++-4.8
+
node_js:
- "6"
- "8"
@@ -18,13 +23,30 @@ node_js:
- "13"
before_install:
- - if [[ ! -f stunnel.tar.gz ]]; then wget -O stunnel.tar.gz ftp://ftp.stunnel.org/stunnel/archive/5.x/stunnel-5.54.tar.gz; fi
- - if [[ ! -f ./stunnel-5.54/configure ]]; then tar -xzf stunnel.tar.gz; fi
- - if [[ ! -f ./stunnel-5.54/src/stunnel ]]; then cd ./stunnel-5.54; ./configure; make; cd ..; fi
- - export PATH="$PATH:$(pwd)/stunnel-5.54/src"
+ - |-
+ case $TRAVIS_OS_NAME in
+ linux)
+ if [[ ! -f stunnel.tar.gz ]]; then wget -O stunnel.tar.gz ftp://ftp.stunnel.org/stunnel/archive/5.x/stunnel-5.54.tar.gz; fi
+ if [[ ! -f ./stunnel-5.54/configure ]]; then tar -xzf stunnel.tar.gz; fi
+ if [[ ! -f ./stunnel-5.54/src/stunnel ]]; then cd ./stunnel-5.54; ./configure; make; cd ..; fi
+ export PATH="$PATH:$(pwd)/stunnel-5.54/src"
+ ;;
+ esac
+ - |-
+ case $TRAVIS_OS_NAME in
+ windows)
+ choco install redis-64
+ C:\ProgramData\chocolatey\lib\redis-64\tools\redis-server.exe --service-install
+ C:\ProgramData\chocolatey\lib\redis-64\tools\redis-server.exe --service-start
+ '@ECHO Redis Started'
+ node --version
+ npm --version
+ ;;
+ esac
cache:
directories:
+ - $HOME/AppData/Local/Temp/chocolatey
- "$TRAVIS_BUILD_DIR/stunnel-5.54"
after_success: npm run coveralls
From 853a837df8bcf221b0d867995379ebc8ba7aefa1 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 13:18:22 +0000
Subject: [PATCH 81/96] chore: add node 10 to builds and wrap windows paths in
quotes
---
.travis.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 473d621827..a2b2941edb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,6 +19,7 @@ addons:
node_js:
- "6"
- "8"
+ - "10"
- "12"
- "13"
@@ -36,9 +37,8 @@ before_install:
case $TRAVIS_OS_NAME in
windows)
choco install redis-64
- C:\ProgramData\chocolatey\lib\redis-64\tools\redis-server.exe --service-install
- C:\ProgramData\chocolatey\lib\redis-64\tools\redis-server.exe --service-start
- '@ECHO Redis Started'
+ "C:\ProgramData\chocolatey\lib\redis-64\tools\redis-server.exe" --service-install
+ "C:\ProgramData\chocolatey\lib\redis-64\tools\redis-server.exe" --service-start
node --version
npm --version
;;
From cb5d163ccfa2602d87a81ac14743af87f57b4b13 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 13:26:26 +0000
Subject: [PATCH 82/96] chore: remove g++ - no longer required
---
.travis.yml | 19 +++----------------
1 file changed, 3 insertions(+), 16 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index a2b2941edb..ffe8c897f3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,17 +5,6 @@ os:
- windows
- linux
-env:
- - CXX=g++-4.8 TRAVIS=true
-
-addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- packages:
- - g++-4.8
-
-
node_js:
- "6"
- "8"
@@ -37,16 +26,14 @@ before_install:
case $TRAVIS_OS_NAME in
windows)
choco install redis-64
- "C:\ProgramData\chocolatey\lib\redis-64\tools\redis-server.exe" --service-install
- "C:\ProgramData\chocolatey\lib\redis-64\tools\redis-server.exe" --service-start
- node --version
- npm --version
+ redis-server --service-install
+ redis-server --service-start
;;
esac
cache:
directories:
- - $HOME/AppData/Local/Temp/chocolatey
+ - "$HOME/AppData/Local/Temp/chocolatey"
- "$TRAVIS_BUILD_DIR/stunnel-5.54"
after_success: npm run coveralls
From 377db618d2fc88d917ed8f470cfefeea3f0c2eae Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 13:33:12 +0000
Subject: [PATCH 83/96] chore: remove appveyor
---
appveyor.yml | 45 ---------------------------------------------
1 file changed, 45 deletions(-)
delete mode 100644 appveyor.yml
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index a67e581b33..0000000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-# http://www.appveyor.com/docs/appveyor-yml
-
-# Test against these versions of Node.js.
-environment:
- matrix:
- - nodejs_version: "6"
- - nodejs_version: "8"
- - nodejs_version: "10"
-# - nodejs_version: "12"
-# - nodejs_version: "13"
-
-pull_requests:
- do_not_increment_build_number: true
-
-platform: Any CPU
-shallow_clone: true
-
-# Install scripts. (runs after repo cloning)
-install:
- # Install Redis
- - nuget install redis-64 -excludeversion
- - redis-64\tools\redis-server.exe --service-install
- - redis-64\tools\redis-server.exe --service-start
- - '@ECHO Redis Started'
- # Get the required Node version
- - ps: Install-Product node $env:nodejs_version
- # Typical npm stuff
- - npm install
-
-# Post-install test scripts.
-test_script:
- # Output useful info for debugging.
- - node --version
- - npm --version
- - cmd: npm t
-
-os:
- - Default Azure
- - Windows Server 2012 R2
-
-# Don't actually build using MSBuild
-build: off
-
-# Set build version format here instead of in the admin panel.
-version: "{build}"
From 46246bea06f620f71e6680ec0b80293c0a702589 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 13:33:47 +0000
Subject: [PATCH 84/96] chore: disable `stop-writes-on-bgsave-error` on windows
(otherwise MISCONF error)
---
.travis.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.travis.yml b/.travis.yml
index ffe8c897f3..0f30c60343 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -28,6 +28,7 @@ before_install:
choco install redis-64
redis-server --service-install
redis-server --service-start
+ redis-cli config set stop-writes-on-bgsave-error no
;;
esac
From a6af0c28893f3ed154537a1ff37fdf64db104e92 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 13:48:58 +0000
Subject: [PATCH 85/96] chore: update travis config
---
.travis.yml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 0f30c60343..80bd615b41 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,8 +2,12 @@ language: node_js
sudo: required
os:
- - windows
- linux
+ - windows
+
+# fix travis windows hanging issue
+# https://travis-ci.community/t/build-doesnt-finish-after-completing-tests/288/25
+env: YARN_GPG=no
node_js:
- "6"
@@ -34,7 +38,6 @@ before_install:
cache:
directories:
- - "$HOME/AppData/Local/Temp/chocolatey"
- "$TRAVIS_BUILD_DIR/stunnel-5.54"
after_success: npm run coveralls
From a7149e39f18e5d7346d442541dcc497402d96705 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 13:58:19 +0000
Subject: [PATCH 86/96] chore: update travis config
---
.travis.yml | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 80bd615b41..1263695a86 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,12 +2,8 @@ language: node_js
sudo: required
os:
- - linux
- windows
-
-# fix travis windows hanging issue
-# https://travis-ci.community/t/build-doesnt-finish-after-completing-tests/288/25
-env: YARN_GPG=no
+ - linux
node_js:
- "6"
@@ -40,10 +36,18 @@ cache:
directories:
- "$TRAVIS_BUILD_DIR/stunnel-5.54"
-after_success: npm run coveralls
before_script:
# Add an IPv6 config - see the corresponding Travis issue
# https://github.com/travis-ci/travis-ci/issues/8361
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6';
fi
+after_script:
+ - |-
+ case $TRAVIS_OS_NAME in
+ windows)
+ redis-server --service-stop
+ ;;
+ esac
+
+after_success: npm run coveralls
From 9f01198c0491e419ed50902fd196df324d8abcee Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 14:13:05 +0000
Subject: [PATCH 87/96] chore: try workaround travis windows hanging issue
---
.travis.yml | 8 +-------
test/node_redis.spec.js | 8 ++++++++
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 1263695a86..18e3dbdeac 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -34,6 +34,7 @@ before_install:
cache:
directories:
+ - "$HOME/AppData/Local/Temp/chocolatey"
- "$TRAVIS_BUILD_DIR/stunnel-5.54"
before_script:
@@ -42,12 +43,5 @@ before_script:
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6';
fi
-after_script:
- - |-
- case $TRAVIS_OS_NAME in
- windows)
- redis-server --service-stop
- ;;
- esac
after_success: npm run coveralls
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index 79f58dd518..83a44f074d 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -11,6 +11,14 @@ var fork = require('child_process').fork;
var redis = config.redis;
var client;
+after(function (done) {
+ if (process.platform !== 'win32' || !process.env.CI) {
+ return done();
+ }
+ require('cross-spawn').sync('redis-server', ['--service-stop'], {});
+ done();
+});
+
describe('The node_redis client', function () {
describe("The 'add_command' method", function () {
From 176bfc210122d0e9d3165e82239f938827f6ea15 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 14:23:47 +0000
Subject: [PATCH 88/96] tests: add comments about travis windows issue
workaround
---
test/node_redis.spec.js | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index 83a44f074d..8937a270c9 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -11,12 +11,20 @@ var fork = require('child_process').fork;
var redis = config.redis;
var client;
+// Currently Travis Windows builds hang after completing if any processes are still running,
+// we shutdown redis-server after all tests complete (can't do this in a
+// `after_script` Travis hook as it hangs before the `after` life cycles)
+// to workaround the issue.
+//
+// See: https://github.com/travis-ci/travis-ci/issues/8082
after(function (done) {
if (process.platform !== 'win32' || !process.env.CI) {
return done();
}
- require('cross-spawn').sync('redis-server', ['--service-stop'], {});
- done();
+ process.nextTick(function () {
+ require('cross-spawn').sync('redis-server', ['--service-stop'], {});
+ done();
+ });
});
describe('The node_redis client', function () {
From 4623cec3c406f6caa0e7aaa6229e46d5d5138281 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 14:35:37 +0000
Subject: [PATCH 89/96] docs: update readme to remove unused badge
---
README.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/README.md b/README.md
index 0167d5dbd0..7ee8b29eb8 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,6 @@
-
From da31ade348f9b98ebc5a3164d59a93576a865906 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 15:44:52 +0000
Subject: [PATCH 90/96] tests: improve coverage & fix unreachable code branches
---
index.js | 24 ++++++------------------
test/commands/set.spec.js | 4 ++++
test/connection.spec.js | 6 +++---
test/multi.spec.js | 2 +-
4 files changed, 14 insertions(+), 22 deletions(-)
diff --git a/index.js b/index.js
index 6cea8bd4c6..439c784c8d 100644
--- a/index.js
+++ b/index.js
@@ -556,12 +556,8 @@ RedisClient.prototype.connection_gone = function (why, error) {
if (this.retry_delay instanceof Error) {
error = this.retry_delay;
}
- var errorMessage = 'Redis connection in broken state: ';
- if (this.retry_totaltime >= this.connect_timeout) {
- errorMessage += 'connection timeout exceeded.';
- } else {
- errorMessage += 'maximum connection attempts exceeded.';
- }
+
+ var errorMessage = 'Redis connection in broken state: retry aborted.';
this.flush_and_error({
message: errorMessage,
@@ -581,13 +577,7 @@ RedisClient.prototype.connection_gone = function (why, error) {
}
if (this.retry_totaltime >= this.connect_timeout) {
- var message = 'Redis connection in broken state: ';
- if (this.retry_totaltime >= this.connect_timeout) {
- message += 'connection timeout exceeded.';
- } else {
- message += 'maximum connection attempts exceeded.';
- }
-
+ var message = 'Redis connection in broken state: connection timeout exceeded.';
this.flush_and_error({
message: message,
code: 'CONNECTION_BROKEN',
@@ -864,11 +854,9 @@ RedisClient.prototype.internal_send_command = function (command_obj) {
if (command_obj.args && command_obj.args.length) {
undefinedArgError.args = command_obj.args;
}
- if (command_obj.callback) {
- command_obj.callback(undefinedArgError);
- return false;
- }
- throw undefinedArgError;
+ // there is always a callback in this scenario
+ command_obj.callback(undefinedArgError);
+ return false;
} else {
// Seems like numbers are converted fast using string concatenation
args_copy[i] = '' + args[i];
diff --git a/test/commands/set.spec.js b/test/commands/set.spec.js
index d2d36491a9..33a8bfa22c 100644
--- a/test/commands/set.spec.js
+++ b/test/commands/set.spec.js
@@ -150,6 +150,10 @@ describe("The 'set' method", function () {
client.get('foo', helper.isNull(done));
});
+ it('calls callback with error if null value is passed', function (done) {
+ client.set('foo', null, helper.isError(done));
+ });
+
it('emit an error with only the key set', function (done) {
client.on('error', function (err) {
assert.equal(err.message, "ERR wrong number of arguments for 'set' command");
diff --git a/test/connection.spec.js b/test/connection.spec.js
index 0913a26ff6..7c153b3926 100644
--- a/test/connection.spec.js
+++ b/test/connection.spec.js
@@ -239,7 +239,7 @@ describe('connection tests', function () {
retryStrategy: function (options) {
if (options.totalRetryTime > 150) {
client.set('foo', 'bar', function (err, res) {
- assert.strictEqual(err.message, 'Redis connection in broken state: maximum connection attempts exceeded.');
+ assert.strictEqual(err.message, 'Redis connection in broken state: retry aborted.');
assert.strictEqual(err.origin.message, 'Connection timeout');
done();
});
@@ -257,7 +257,7 @@ describe('connection tests', function () {
retry_strategy: function (options) {
if (options.total_retry_time > 150) {
client.set('foo', 'bar', function (err, res) {
- assert.strictEqual(err.message, 'Redis connection in broken state: maximum connection attempts exceeded.');
+ assert.strictEqual(err.message, 'Redis connection in broken state: retry aborted.');
assert.strictEqual(err.code, 'CONNECTION_BROKEN');
assert.strictEqual(err.origin.code, 'ECONNREFUSED');
done();
@@ -287,7 +287,7 @@ describe('connection tests', function () {
}, 50);
client.on('error', function (err) {
if (err instanceof redis.AbortError) {
- assert.strictEqual(err.message, 'Redis connection in broken state: maximum connection attempts exceeded.');
+ assert.strictEqual(err.message, 'Redis connection in broken state: retry aborted.');
assert.strictEqual(err.code, 'CONNECTION_BROKEN');
unhookIntercept();
redis.debugMode = false;
diff --git a/test/multi.spec.js b/test/multi.spec.js
index 498168f9d5..2465dfc2d0 100644
--- a/test/multi.spec.js
+++ b/test/multi.spec.js
@@ -234,7 +234,7 @@ describe("The 'multi' method", function () {
});
client.multi([['set', 'foo', 'bar'], ['get', 'foo']]).exec(function (err, res) {
- assert(/Redis connection in broken state: maximum connection attempts exceeded/.test(err.message));
+ assert(/Redis connection in broken state: retry aborted/.test(err.message));
assert.strictEqual(err.errors.length, 2);
assert.strictEqual(err.errors[0].args.length, 2);
});
From 61318e6ed6be71ddb5458d17d9d874ad9314c97e Mon Sep 17 00:00:00 2001
From: Salakar
Date: Sun, 9 Feb 2020 15:46:49 +0000
Subject: [PATCH 91/96] 3.0.2
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index e36c892484..45c7040863 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "redis",
- "version": "3.0.1",
+ "version": "3.0.2",
"description": "A high performance Redis client.",
"keywords": [
"database",
From f2050f9daf00f9cbfe7ab9756ceb273a32f878b1 Mon Sep 17 00:00:00 2001
From: Mike Diarmid
Date: Tue, 11 Feb 2020 00:17:09 +0000
Subject: [PATCH 92/96] tests: setup GitHub Actions to replace Travis (#1497)
Additionally adds testing against many Node.js versions and Redis versions.
---
.eslintrc | 1 +
.github/workflows/benchmark.yml | 38 +++++++++++++++++++++
.github/workflows/linting.yml | 31 +++++++++++++++++
.github/workflows/tests.yml | 52 +++++++++++++++++++++++++++++
.github/workflows/tests_windows.yml | 49 +++++++++++++++++++++++++++
.gitignore | 1 +
.npmignore | 1 +
.travis.yml | 47 --------------------------
package.json | 6 ++--
test/commands/zadd.spec.js | 6 +++-
test/lib/redis-process.js | 15 +++++++--
test/node_redis.spec.js | 15 ++++-----
test/rename.spec.js | 4 ++-
13 files changed, 204 insertions(+), 62 deletions(-)
create mode 100644 .github/workflows/benchmark.yml
create mode 100644 .github/workflows/linting.yml
create mode 100644 .github/workflows/tests.yml
create mode 100644 .github/workflows/tests_windows.yml
delete mode 100644 .travis.yml
diff --git a/.eslintrc b/.eslintrc
index 75c73341b0..81e5e9b9cf 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -102,6 +102,7 @@ rules:
globals:
it: true
describe: true
+ xdescribe: true
before: true
after: true
beforeEach: true
diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml
new file mode 100644
index 0000000000..88974e42da
--- /dev/null
+++ b/.github/workflows/benchmark.yml
@@ -0,0 +1,38 @@
+name: Benchmarking
+
+on: [pull_request]
+
+jobs:
+ benchmark:
+ name: Benchmark
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ node-version: [8.x, 10.x, 12.x]
+ redis-version: [5]
+
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Setup Redis
+ uses: shogo82148/actions-setup-redis@v1.0.1
+ with:
+ redis-version: ${{ matrix.redis-version }}
+ auto-start: "true"
+
+ - run: npm i --no-audit --prefer-offline
+ - name: Run Benchmark
+ run: npm run benchmark > benchmark-output.txt && cat benchmark-output.txt
+ - name: Upload Benchmark Result
+ uses: actions/upload-artifact@v1
+ with:
+ name: benchmark-output.txt
+ path: benchmark-output.txt
diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml
new file mode 100644
index 0000000000..08a5f1e5ac
--- /dev/null
+++ b/.github/workflows/linting.yml
@@ -0,0 +1,31 @@
+name: Linting
+
+on: [pull_request]
+
+jobs:
+ eslint:
+ name: ESLint
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+ - uses: actions/setup-node@v1
+ with:
+ node-version: 12
+ - run: npm i --no-audit --prefer-offline
+ - name: Test Code Linting
+ run: npm run lint
+ - name: Save Code Linting Report JSON
+ run: npm run lint:report
+ continue-on-error: true
+ - name: Annotate Code Linting Results
+ uses: ataylorme/eslint-annotate-action@1.0.4
+ with:
+ repo-token: "${{ secrets.GITHUB_TOKEN }}"
+ report-json: "eslint-report.json"
+ - name: Upload ESLint report
+ uses: actions/upload-artifact@v1
+ with:
+ name: eslint-report.json
+ path: eslint-report.json
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000000..b680815084
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,52 @@
+name: Tests
+
+on: [pull_request]
+
+jobs:
+ testing:
+ name: Test
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ node-version: [6.x, 8.x, 10.x, 12.x]
+ redis-version: [4.x, 5.x]
+
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Setup Redis
+ uses: shogo82148/actions-setup-redis@v1.0.1
+ with:
+ redis-version: ${{ matrix.redis-version }}
+ auto-start: "false"
+
+ - name: Disable IPv6
+ run: sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6';
+
+ - name: Setup Stunnel
+ run: sudo apt-get install stunnel4
+
+ - name: Install Packages
+ run: npm i --no-audit --prefer-offline
+
+ - name: Run Tests
+ run: npm test
+
+ - name: Submit Coverage
+ run: npm run coveralls
+ env:
+ COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
+
+ - name: Upload Coverage Report
+ uses: actions/upload-artifact@v1
+ with:
+ name: coverage
+ path: coverage
diff --git a/.github/workflows/tests_windows.yml b/.github/workflows/tests_windows.yml
new file mode 100644
index 0000000000..e2e8f53cda
--- /dev/null
+++ b/.github/workflows/tests_windows.yml
@@ -0,0 +1,49 @@
+name: Tests Windows
+
+on: [pull_request]
+
+jobs:
+ testing-windows:
+ name: Test Windows
+ runs-on: windows-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ node-version: [6.x, 8.x, 10.x, 12.x]
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+
+ - name: Install Redis
+ uses: crazy-max/ghaction-chocolatey@v1
+ with:
+ args: install redis-64 --no-progress
+
+ - name: Start Redis
+ run: |
+ redis-server --service-install
+ redis-server --service-start
+ redis-cli config set stop-writes-on-bgsave-error no
+
+ - name: Setup Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+
+ - name: Install Packages
+ run: npm i --no-audit --prefer-offline
+
+ - name: Run Tests
+ run: npm test
+
+ - name: Submit Coverage
+ run: npm run coveralls
+ env:
+ COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_TOKEN }}
+
+ - name: Upload Coverage Report
+ uses: actions/upload-artifact@v1
+ with:
+ name: coverage
+ path: coverage
diff --git a/.gitignore b/.gitignore
index 037016a27f..64b4143dc6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,4 @@ package-lock.json
# VisualStudioCode IDEs
.vscode
.vs
+eslint-report.json
diff --git a/.npmignore b/.npmignore
index 262ee0c0b4..f1cf466f08 100644
--- a/.npmignore
+++ b/.npmignore
@@ -19,3 +19,4 @@ CODE_OF_CONDUCT.md
appveyor.yml
package-lock.json
.prettierrc
+eslint-report.json
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 18e3dbdeac..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-language: node_js
-sudo: required
-
-os:
- - windows
- - linux
-
-node_js:
- - "6"
- - "8"
- - "10"
- - "12"
- - "13"
-
-before_install:
- - |-
- case $TRAVIS_OS_NAME in
- linux)
- if [[ ! -f stunnel.tar.gz ]]; then wget -O stunnel.tar.gz ftp://ftp.stunnel.org/stunnel/archive/5.x/stunnel-5.54.tar.gz; fi
- if [[ ! -f ./stunnel-5.54/configure ]]; then tar -xzf stunnel.tar.gz; fi
- if [[ ! -f ./stunnel-5.54/src/stunnel ]]; then cd ./stunnel-5.54; ./configure; make; cd ..; fi
- export PATH="$PATH:$(pwd)/stunnel-5.54/src"
- ;;
- esac
- - |-
- case $TRAVIS_OS_NAME in
- windows)
- choco install redis-64
- redis-server --service-install
- redis-server --service-start
- redis-cli config set stop-writes-on-bgsave-error no
- ;;
- esac
-
-cache:
- directories:
- - "$HOME/AppData/Local/Temp/chocolatey"
- - "$TRAVIS_BUILD_DIR/stunnel-5.54"
-
-before_script:
- # Add an IPv6 config - see the corresponding Travis issue
- # https://github.com/travis-ci/travis-ci/issues/8361
- - if [ "${TRAVIS_OS_NAME}" == "linux" ]; then
- sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6';
- fi
-
-after_success: npm run coveralls
diff --git a/package.json b/package.json
index 45c7040863..75489c3ec4 100644
--- a/package.json
+++ b/package.json
@@ -30,8 +30,10 @@
"coveralls": "nyc report --reporter=text-lcov | coveralls",
"coverage": "nyc report --reporter=html",
"benchmark": "node benchmarks/multi_bench.js",
- "test": "nyc --cache mocha ./test/*.js ./test/commands/*.js --timeout=8000",
- "lint": "eslint . --fix && npm run coverage",
+ "test": "nyc --cache mocha ./test/*.js ./test/commands/*.js --timeout=8000 && npm run coverage",
+ "lint": "eslint .",
+ "lint:fix": "eslint . --fix",
+ "lint:report": "eslint --output-file=eslint-report.json --format=json .",
"compare": "node benchmarks/diff_multi_bench_output.js beforeBench.txt afterBench.txt"
},
"dependencies": {
diff --git a/test/commands/zadd.spec.js b/test/commands/zadd.spec.js
index 827630a389..f22963416c 100644
--- a/test/commands/zadd.spec.js
+++ b/test/commands/zadd.spec.js
@@ -34,7 +34,11 @@ describe("The 'zadd' method", function () {
client.zrange('infinity', 0, -1, 'WITHSCORES', function (err, res) {
assert.equal(res[5], 'inf');
assert.equal(res[1], '-inf');
- assert.equal(res[3], '9.9999999999999992e+22');
+ if (process.platform !== 'win32') {
+ assert.equal(res[3], '9.9999999999999992e+22');
+ } else {
+ assert.equal(res[3], '9.9999999999999992e+022');
+ }
done();
});
});
diff --git a/test/lib/redis-process.js b/test/lib/redis-process.js
index ce2f881edd..23ff2e1815 100644
--- a/test/lib/redis-process.js
+++ b/test/lib/redis-process.js
@@ -17,7 +17,7 @@ function waitForRedis (available, cb, port) {
var running = false;
var socket = '/tmp/redis.sock';
if (port) {
- // We have to distinguishe the redis sockets if we have more than a single redis instance running
+ // We have to distinguish the redis sockets if we have more than a single redis instance running
socket = '/tmp/redis' + port + '.sock';
}
port = port || config.PORT;
@@ -51,6 +51,14 @@ function waitForRedis (available, cb, port) {
module.exports = {
start: function (done, conf, port) {
var spawnFailed = false;
+ if (process.platform === 'win32') return done(null, {
+ spawnFailed: function () {
+ return spawnFailed;
+ },
+ stop: function (done) {
+ return done();
+ }
+ });
// spawn redis with our testing configuration.
var confFile = conf || path.resolve(__dirname, '../conf/redis.conf');
var rp = spawn('redis-server', [confFile], {});
@@ -58,7 +66,10 @@ module.exports = {
// capture a failure booting redis, and give
// the user running the test some directions.
rp.once('exit', function (code) {
- if (code !== 0) spawnFailed = true;
+ if (code !== 0) {
+ spawnFailed = true;
+ throw new Error('TESTS: Redis Spawn Failed');
+ }
});
// wait for redis to become available, by
diff --git a/test/node_redis.spec.js b/test/node_redis.spec.js
index 8937a270c9..a2c7fac69e 100644
--- a/test/node_redis.spec.js
+++ b/test/node_redis.spec.js
@@ -11,20 +11,17 @@ var fork = require('child_process').fork;
var redis = config.redis;
var client;
-// Currently Travis Windows builds hang after completing if any processes are still running,
-// we shutdown redis-server after all tests complete (can't do this in a
-// `after_script` Travis hook as it hangs before the `after` life cycles)
-// to workaround the issue.
-//
-// See: https://github.com/travis-ci/travis-ci/issues/8082
+// Currently GitHub Actions on Windows (and event travis) builds hang after completing if
+// any processes are still running, we shutdown redis-server after all tests complete (can't do this in a
+// `after_script` hook as it hangs before the `after` life cycles) to workaround the issue.
after(function (done) {
- if (process.platform !== 'win32' || !process.env.CI) {
+ if (process.platform !== 'win32' || !process.env.GITHUB_ACTION) {
return done();
}
- process.nextTick(function () {
+ setTimeout(function () {
require('cross-spawn').sync('redis-server', ['--service-stop'], {});
done();
- });
+ }, 2000);
});
describe('The node_redis client', function () {
diff --git a/test/rename.spec.js b/test/rename.spec.js
index f43eee35ca..68adc5699f 100644
--- a/test/rename.spec.js
+++ b/test/rename.spec.js
@@ -10,7 +10,9 @@ if (process.platform === 'win32') {
return;
}
-describe('rename commands', function () {
+// TODO these tests are causing flakey tests - looks like redis-server is not
+// being started with new configuration after or before these tests
+xdescribe('rename commands', function () {
before(function (done) {
helper.stopRedis(function () {
helper.startRedis('./conf/rename.conf', done);
From cd357652ca377fc1ff999ea2b95eaa6812ec18e0 Mon Sep 17 00:00:00 2001
From: Salakar
Date: Tue, 11 Feb 2020 00:19:13 +0000
Subject: [PATCH 93/96] chore: run tests on push
---
.github/workflows/tests.yml | 2 +-
.github/workflows/tests_windows.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index b680815084..a7829a9d1b 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -1,6 +1,6 @@
name: Tests
-on: [pull_request]
+on: [push]
jobs:
testing:
diff --git a/.github/workflows/tests_windows.yml b/.github/workflows/tests_windows.yml
index e2e8f53cda..504cb6a4f8 100644
--- a/.github/workflows/tests_windows.yml
+++ b/.github/workflows/tests_windows.yml
@@ -1,6 +1,6 @@
name: Tests Windows
-on: [pull_request]
+on: [push]
jobs:
testing-windows:
From 0041e3e53d5292b13d96ce076653c5b91b314fda Mon Sep 17 00:00:00 2001
From: Salakar
Date: Tue, 11 Feb 2020 00:29:04 +0000
Subject: [PATCH 94/96] docs: replace travis badges with GH actions badges
---
README.md | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 7ee8b29eb8..6cae87a270 100644
--- a/README.md
+++ b/README.md
@@ -9,10 +9,11 @@
---
-
-
-
-
+
+
+
+
+
From 9e86cf3c52d24f5834a0f1be7be0d643a6186fd8 Mon Sep 17 00:00:00 2001
From: Nikhil Savaliya
Date: Mon, 6 Jul 2020 13:20:12 +0530
Subject: [PATCH 95/96] Update README.md
In multi example
replacing err => setError
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 6cae87a270..de22112440 100644
--- a/README.md
+++ b/README.md
@@ -638,7 +638,7 @@ client.watch("foo", function(watchError) {
* If err is null, it means Redis successfully attempted
* the operation.
*/
- if (execError) throw err;
+ if (execError) throw execError;
/**
* If results === null, it means that a concurrent client
@@ -675,7 +675,7 @@ clients.watcher.watch("foo", function(watchError) {
// if you comment out the next line, the transaction will work
clients.modifier.set("foo", Math.random(), setError => {
- if (setError) throw err;
+ if (setError) throw setError;
});
// using a setTimeout here to ensure that the MULTI/EXEC will come after the SET.
From e4cb073be29ca2e346f40e4dfe9050f6e3be06ee Mon Sep 17 00:00:00 2001
From: Likai Ren
Date: Wed, 3 Feb 2021 13:25:37 +0200
Subject: [PATCH 96/96] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 6cae87a270..abf95b10fa 100644
--- a/README.md
+++ b/README.md
@@ -394,7 +394,7 @@ responses using JavaScript syntax.
```js
client.hmset("key", "foo", "bar", "hello", "world");
-client.hgetall("hosts", function(err, value) {
+client.hgetall("key", function(err, value) {
console.log(value.foo); // > "bar"
console.log(value.hello); // > "world"
});