redis 2.6.3 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -197,7 +197,7 @@ __Tip:__ If the Redis server runs on the same machine as the client consider usi
197
197
  | db | null | If set, client will run Redis `select` command on connect. |
198
198
  | 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. |
199
199
  | disable_resubscribing | false | If set to `true`, a client won't resubscribe after disconnecting. |
200
- | rename_commands | null | Passing an object with renamed commands to use instead of the original functions. See the [Redis security topics](http://redis.io/topics/security) for more info. |
200
+ | 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. |
201
201
  | 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). |
202
202
  | 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. |
203
203
  | 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. |
@@ -224,7 +224,7 @@ retry_strategy example
224
224
  ```js
225
225
  var client = redis.createClient({
226
226
  retry_strategy: function (options) {
227
- if (options.error.code === 'ECONNREFUSED') {
227
+ if (options.error && options.error.code === 'ECONNREFUSED') {
228
228
  // End reconnecting on a specific error and flush all commands with a individual error
229
229
  return new Error('The server refused the connection');
230
230
  }
@@ -237,7 +237,7 @@ var client = redis.createClient({
237
237
  return undefined;
238
238
  }
239
239
  // reconnect after
240
- return Math.max(options.attempt * 100, 3000);
240
+ return Math.min(options.attempt * 100, 3000);
241
241
  }
242
242
  });
243
243
  ```
@@ -296,10 +296,15 @@ client.get("foo_rand000000000000", function (err, reply) {
296
296
 
297
297
  ## Error handling (>= v.2.6)
298
298
 
299
- All redis errors are returned as `ReplyError`.
300
- All unresolved commands that get rejected due to what ever reason return a `AbortError`.
301
- As subclass of the `AbortError` a `AggregateError` exists. This is emitted in case multiple unresolved commands without callback got rejected in debug_mode.
302
- They are all aggregated and a single error is emitted in that case.
299
+ Currently the following error subclasses exist:
300
+
301
+ * `RedisError`: _All errors_ returned by the client
302
+ * `ReplyError` subclass of `RedisError`: All errors returned by __Redis__ itself
303
+ * `AbortError` subclass of `RedisError`: All commands that could not finish due to what ever reason
304
+ * `ParserError` subclass of `RedisError`: Returned in case of a parser error (this should not happen)
305
+ * `AggregateError` subclass of `AbortError`: Emitted in case multiple unresolved commands without callback got rejected in debug_mode instead of lots of `AbortError`s.
306
+
307
+ All error classes are exported by the module.
303
308
 
304
309
  Example:
305
310
  ```js
package/changelog.md CHANGED
@@ -1,6 +1,36 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## v.2.7.1 - 14 Mar, 2017
5
+
6
+ Bugfixes
7
+
8
+ - Fixed monitor mode not working in combination with IPv6 (2.6.0 regression)
9
+
10
+ ## v.2.7.0 - 11 Mar, 2017
11
+
12
+ Features
13
+
14
+ - All returned errors are from now a subclass of `RedisError`.
15
+
16
+ Bugfixes
17
+
18
+ - Fixed rename_commands not accepting `null` as value
19
+ - Fixed `AbortError`s and `AggregateError`s not showing the error message in the stack trace
20
+
21
+ ## v.2.6.5 - 15 Jan, 2017
22
+
23
+ Bugfixes
24
+
25
+ - Fixed parser not being reset in case the redis connection closed ASAP for overcoming of output buffer limits
26
+ - Fixed parser reset if (p)message_buffer listener is attached
27
+
28
+ ## v.2.6.4 - 12 Jan, 2017
29
+
30
+ Bugfixes
31
+
32
+ - Fixed monitor mode not working in combination with IPv6, sockets or lua scripts (2.6.0 regression)
33
+
4
34
  ## v.2.6.3 - 31 Oct, 2016
5
35
 
6
36
  Bugfixes
package/index.js CHANGED
@@ -156,8 +156,6 @@ function RedisClient (options, stream) {
156
156
  this.buffers = options.return_buffers || options.detect_buffers;
157
157
  this.options = options;
158
158
  this.reply = 'ON'; // Returning replies is the default
159
- // Init parser
160
- this.reply_parser = create_parser(this);
161
159
  this.create_stream();
162
160
  // The listeners will not be attached right away, so let's print the deprecation message while the listener is attached
163
161
  this.on('newListener', function (event) {
@@ -171,10 +169,16 @@ function RedisClient (options, stream) {
171
169
  'The drain event listener is deprecated and will be removed in v.3.0.0.\n' +
172
170
  'If you want to keep on listening to this event please listen to the stream drain event directly.'
173
171
  );
174
- } else if (event === 'message_buffer' || event === 'pmessage_buffer' || event === 'messageBuffer' || event === 'pmessageBuffer' && !this.buffers) {
172
+ } else if ((event === 'message_buffer' || event === 'pmessage_buffer' || event === 'messageBuffer' || event === 'pmessageBuffer') && !this.buffers && !this.message_buffers) {
173
+ if (this.reply_parser.name !== 'javascript') {
174
+ return this.warn(
175
+ 'You attached the "' + event + '" listener without the returnBuffers option set to true.\n' +
176
+ 'Please use the JavaScript parser or set the returnBuffers option to true to return buffers.'
177
+ );
178
+ }
179
+ this.reply_parser.optionReturnBuffers = true;
175
180
  this.message_buffers = true;
176
181
  this.handle_reply = handle_detect_buffers_reply;
177
- this.reply_parser = create_parser(this);
178
182
  }
179
183
  });
180
184
  }
@@ -224,6 +228,9 @@ function create_parser (self) {
224
228
  RedisClient.prototype.create_stream = function () {
225
229
  var self = this;
226
230
 
231
+ // Init parser
232
+ this.reply_parser = create_parser(this);
233
+
227
234
  if (this.options.stream) {
228
235
  // Only add the listeners once in case of a reconnect try (that won't work)
229
236
  if (this.stream) {
@@ -791,9 +798,6 @@ function return_pub_sub (self, reply) {
791
798
  }
792
799
 
793
800
  RedisClient.prototype.return_reply = function (reply) {
794
- // If in monitor mode, all normal commands are still working and we only want to emit the streamlined commands
795
- // As this is not the average use case and monitor is expensive anyway, let's change the code here, to improve
796
- // the average performance of all other commands in case of no monitor mode
797
801
  if (this.monitoring) {
798
802
  var replyStr;
799
803
  if (this.buffers && Buffer.isBuffer(reply)) {
@@ -801,8 +805,7 @@ RedisClient.prototype.return_reply = function (reply) {
801
805
  } else {
802
806
  replyStr = reply;
803
807
  }
804
- // While reconnecting the redis server does not recognize the client as in monitor mode anymore
805
- // Therefore the monitor command has to finish before it catches further commands
808
+ // If in monitor mode, all normal commands are still working and we only want to emit the streamlined commands
806
809
  if (typeof replyStr === 'string' && utils.monitor_regex.test(replyStr)) {
807
810
  var timestamp = replyStr.slice(0, replyStr.indexOf(' '));
808
811
  var args = replyStr.slice(replyStr.indexOf('"') + 1, -1).split('" "').map(function (elem) {
@@ -928,7 +931,7 @@ RedisClient.prototype.internal_send_command = function (command_obj) {
928
931
  args_copy[i] = this.options.prefix + args_copy[i];
929
932
  }
930
933
  }
931
- if (typeof this.options.rename_commands !== 'undefined' && this.options.rename_commands[command]) {
934
+ if (this.options.rename_commands && this.options.rename_commands[command]) {
932
935
  command = this.options.rename_commands[command];
933
936
  }
934
937
  // Always use 'Multi bulk commands', but if passed any Buffer args, then do multiple writes, one for each arg.
@@ -1084,6 +1087,8 @@ exports.RedisClient = RedisClient;
1084
1087
  exports.print = utils.print;
1085
1088
  exports.Multi = require('./lib/multi');
1086
1089
  exports.AbortError = errorClasses.AbortError;
1090
+ exports.RedisError = Parser.RedisError;
1091
+ exports.ParserError = Parser.ParserError;
1087
1092
  exports.ReplyError = Parser.ReplyError;
1088
1093
  exports.AggregateError = errorClasses.AggregateError;
1089
1094
 
@@ -1,42 +1,55 @@
1
1
  'use strict';
2
2
 
3
3
  var util = require('util');
4
+ var assert = require('assert');
5
+ var RedisError = require('redis-parser').RedisError;
6
+ var ADD_STACKTRACE = false;
4
7
 
5
- function AbortError (obj) {
6
- Error.captureStackTrace(this, this.constructor);
8
+ function AbortError (obj, stack) {
9
+ assert(obj, 'The options argument is required');
10
+ assert.strictEqual(typeof obj, 'object', 'The options argument has to be of type object');
11
+
12
+ RedisError.call(this, obj.message, ADD_STACKTRACE);
7
13
  Object.defineProperty(this, 'message', {
8
14
  value: obj.message || '',
9
15
  configurable: true,
10
16
  writable: true
11
17
  });
18
+ if (stack || stack === undefined) {
19
+ Error.captureStackTrace(this, AbortError);
20
+ }
12
21
  for (var keys = Object.keys(obj), key = keys.pop(); key; key = keys.pop()) {
13
22
  this[key] = obj[key];
14
23
  }
15
24
  }
16
25
 
17
26
  function AggregateError (obj) {
18
- Error.captureStackTrace(this, this.constructor);
27
+ assert(obj, 'The options argument is required');
28
+ assert.strictEqual(typeof obj, 'object', 'The options argument has to be of type object');
29
+
30
+ AbortError.call(this, obj, ADD_STACKTRACE);
19
31
  Object.defineProperty(this, 'message', {
20
32
  value: obj.message || '',
21
33
  configurable: true,
22
34
  writable: true
23
35
  });
36
+ Error.captureStackTrace(this, AggregateError);
24
37
  for (var keys = Object.keys(obj), key = keys.pop(); key; key = keys.pop()) {
25
38
  this[key] = obj[key];
26
39
  }
27
40
  }
28
41
 
29
- util.inherits(AbortError, Error);
42
+ util.inherits(AbortError, RedisError);
30
43
  util.inherits(AggregateError, AbortError);
31
44
 
32
45
  Object.defineProperty(AbortError.prototype, 'name', {
33
46
  value: 'AbortError',
34
- // configurable: true,
47
+ configurable: true,
35
48
  writable: true
36
49
  });
37
50
  Object.defineProperty(AggregateError.prototype, 'name', {
38
51
  value: 'AggregateError',
39
- // configurable: true,
52
+ configurable: true,
40
53
  writable: true
41
54
  });
42
55
 
package/lib/utils.js CHANGED
@@ -127,7 +127,7 @@ module.exports = {
127
127
  reply_to_object: replyToObject,
128
128
  print: print,
129
129
  err_code: /^([A-Z]+)\s+(.+)$/,
130
- monitor_regex: /^[0-9]{10,11}\.[0-9]+ \[[0-9]{1,3} [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]{1,5}\].*/,
130
+ monitor_regex: /^[0-9]{10,11}\.[0-9]+ \[[0-9]+ .+\]( ".+?")+$/,
131
131
  clone: convenienceClone,
132
132
  callback_or_emit: callbackOrEmit,
133
133
  reply_in_order: replyInOrder
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "redis",
3
- "version": "2.6.3",
3
+ "version": "2.7.1",
4
4
  "description": "Redis client library",
5
5
  "keywords": [
6
6
  "database",
@@ -21,13 +21,13 @@
21
21
  "coverage": "nyc report --reporter=html",
22
22
  "benchmark": "node benchmarks/multi_bench.js",
23
23
  "test": "nyc --cache mocha ./test/*.js ./test/commands/*.js --timeout=8000",
24
- "posttest": "eslint . --fix && npm run coverage",
24
+ "lint": "eslint . --fix && npm run coverage",
25
25
  "compare": "node benchmarks/diff_multi_bench_output.js beforeBench.txt afterBench.txt"
26
26
  },
27
27
  "dependencies": {
28
28
  "double-ended-queue": "^2.1.0-0",
29
29
  "redis-commands": "^1.2.0",
30
- "redis-parser": "^2.0.0"
30
+ "redis-parser": "^2.5.0"
31
31
  },
32
32
  "engines": {
33
33
  "node": ">=0.10.0"
@@ -36,9 +36,9 @@
36
36
  "bluebird": "^3.0.2",
37
37
  "coveralls": "^2.11.2",
38
38
  "intercept-stdout": "~0.1.2",
39
- "eslint": "^2.5.0",
39
+ "eslint": "^3.5.0",
40
40
  "metrics": "^0.1.9",
41
- "mocha": "^2.3.2",
41
+ "mocha": "^3.1.2",
42
42
  "nyc": "^8.3.0",
43
43
  "tcp-port-used": "^0.1.2",
44
44
  "uuid": "^2.0.1",