ioredis 4.23.0 → 4.24.2
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/Changelog.md +28 -0
- package/README.md +5 -2
- package/built/cluster/ClusterOptions.js +1 -0
- package/built/cluster/index.js +14 -8
- package/built/command.js +6 -15
- package/built/connectors/SentinelConnector/index.js +3 -0
- package/built/connectors/StandaloneConnector.js +3 -0
- package/built/pipeline.js +2 -1
- package/built/redis/index.js +13 -2
- package/package.json +3 -3
package/Changelog.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## [4.24.2](https://github.com/luin/ioredis/compare/v4.24.1...v4.24.2) (2021-03-14)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* properly handle instant stream errors ([#1299](https://github.com/luin/ioredis/issues/1299)) ([0327ef5](https://github.com/luin/ioredis/commit/0327ef5a57481042d3f7d306917f55ef04f3a6cc))
|
|
7
|
+
|
|
8
|
+
## [4.24.1](https://github.com/luin/ioredis/compare/v4.24.0...v4.24.1) (2021-03-14)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **cluster:** reconnect when failing to refresh slots cache for all nodes ([8524eea](https://github.com/luin/ioredis/commit/8524eeaedaa2542f119f2b65ab8e2f15644b474e))
|
|
14
|
+
|
|
15
|
+
# [4.24.0](https://github.com/luin/ioredis/compare/v4.23.1...v4.24.0) (2021-03-14)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* **cluster:** support retrying MOVED with a delay ([#1254](https://github.com/luin/ioredis/issues/1254)) ([8599981](https://github.com/luin/ioredis/commit/8599981141e8357f5ae2706fffb55010490bf002))
|
|
21
|
+
|
|
22
|
+
## [4.23.1](https://github.com/luin/ioredis/compare/v4.23.0...v4.23.1) (2021-03-14)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* **cluster:** issues when code is processed by babel ([#1298](https://github.com/luin/ioredis/issues/1298)) ([bfc194d](https://github.com/luin/ioredis/commit/bfc194dcad2af527e802d6f5b060f0b0779e840d)), closes [#1288](https://github.com/luin/ioredis/issues/1288)
|
|
28
|
+
|
|
1
29
|
# [4.23.0](https://github.com/luin/ioredis/compare/v4.22.0...v4.23.0) (2021-02-25)
|
|
2
30
|
|
|
3
31
|
|
package/README.md
CHANGED
|
@@ -889,9 +889,12 @@ cluster.get("foo", (err, res) => {
|
|
|
889
889
|
will resend the commands after the specified time (in ms).
|
|
890
890
|
- `retryDelayOnTryAgain`: If this option is a number (by default, it is `100`), the client
|
|
891
891
|
will resend the commands rejected with `TRYAGAIN` error after the specified time (in ms).
|
|
892
|
+
- `retryDelayOnMoved`: By default, this value is `0` (in ms), which means when a `MOVED` error is received, the client will resend
|
|
893
|
+
the command instantly to the node returned together with the `MOVED` error. However, sometimes it takes time for a cluster to become
|
|
894
|
+
state stabilized after a failover, so adding a delay before resending can prevent a ping pong effect.
|
|
892
895
|
- `redisOptions`: Default options passed to the constructor of `Redis` when connecting to a node.
|
|
893
|
-
- `slotsRefreshTimeout`: Milliseconds before a timeout occurs while refreshing slots from the cluster (default `1000`)
|
|
894
|
-
- `slotsRefreshInterval`: Milliseconds between every automatic slots refresh (default `5000`)
|
|
896
|
+
- `slotsRefreshTimeout`: Milliseconds before a timeout occurs while refreshing slots from the cluster (default `1000`).
|
|
897
|
+
- `slotsRefreshInterval`: Milliseconds between every automatic slots refresh (default `5000`).
|
|
895
898
|
|
|
896
899
|
### Read-write splitting
|
|
897
900
|
|
package/built/cluster/index.js
CHANGED
|
@@ -185,12 +185,7 @@ class Cluster extends events_1.EventEmitter {
|
|
|
185
185
|
this.once("refresh", refreshListener);
|
|
186
186
|
this.once("close", closeListener);
|
|
187
187
|
this.once("close", this.handleCloseEvent.bind(this));
|
|
188
|
-
this.refreshSlotsCache(
|
|
189
|
-
if (err && err.message === "Failed to refresh slots cache.") {
|
|
190
|
-
redis_1.default.prototype.silentEmit.call(this, "error", err);
|
|
191
|
-
this.connectionPool.reset([]);
|
|
192
|
-
}
|
|
193
|
-
}.bind(this));
|
|
188
|
+
this.refreshSlotsCache();
|
|
194
189
|
this.subscriber.start();
|
|
195
190
|
})
|
|
196
191
|
.catch((err) => {
|
|
@@ -390,6 +385,8 @@ class Cluster extends events_1.EventEmitter {
|
|
|
390
385
|
function tryNode(index) {
|
|
391
386
|
if (index === nodes.length) {
|
|
392
387
|
const error = new ClusterAllFailedError_1.default("Failed to refresh slots cache.", lastNodeError);
|
|
388
|
+
redis_1.default.prototype.silentEmit.call(_this, "error", error);
|
|
389
|
+
_this.connectionPool.reset([]);
|
|
393
390
|
return wrapper(error);
|
|
394
391
|
}
|
|
395
392
|
const node = nodes[index];
|
|
@@ -608,8 +605,17 @@ class Cluster extends events_1.EventEmitter {
|
|
|
608
605
|
return;
|
|
609
606
|
}
|
|
610
607
|
const errv = error.message.split(" ");
|
|
611
|
-
if (errv[0] === "MOVED"
|
|
612
|
-
|
|
608
|
+
if (errv[0] === "MOVED") {
|
|
609
|
+
const timeout = this.options.retryDelayOnMoved;
|
|
610
|
+
if (timeout && typeof timeout === "number") {
|
|
611
|
+
this.delayQueue.push("moved", handlers.moved.bind(null, errv[1], errv[2]), { timeout });
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
handlers.moved(errv[1], errv[2]);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
else if (errv[0] === "ASK") {
|
|
618
|
+
handlers.ask(errv[1], errv[2]);
|
|
613
619
|
}
|
|
614
620
|
else if (errv[0] === "TRYAGAIN") {
|
|
615
621
|
this.delayQueue.push("tryagain", handlers.tryagain, {
|
package/built/command.js
CHANGED
|
@@ -274,9 +274,7 @@ const msetArgumentTransformer = function (args) {
|
|
|
274
274
|
}
|
|
275
275
|
return args;
|
|
276
276
|
};
|
|
277
|
-
|
|
278
|
-
Command.setArgumentTransformer("msetnx", msetArgumentTransformer);
|
|
279
|
-
Command.setArgumentTransformer("hmset", function (args) {
|
|
277
|
+
const hsetArgumentTransformer = function (args) {
|
|
280
278
|
if (args.length === 2) {
|
|
281
279
|
if (typeof Map !== "undefined" && args[1] instanceof Map) {
|
|
282
280
|
return [args[0]].concat(utils_1.convertMapToArray(args[1]));
|
|
@@ -286,7 +284,11 @@ Command.setArgumentTransformer("hmset", function (args) {
|
|
|
286
284
|
}
|
|
287
285
|
}
|
|
288
286
|
return args;
|
|
289
|
-
}
|
|
287
|
+
};
|
|
288
|
+
Command.setArgumentTransformer("mset", msetArgumentTransformer);
|
|
289
|
+
Command.setArgumentTransformer("msetnx", msetArgumentTransformer);
|
|
290
|
+
Command.setArgumentTransformer("hset", hsetArgumentTransformer);
|
|
291
|
+
Command.setArgumentTransformer("hmset", hsetArgumentTransformer);
|
|
290
292
|
Command.setReplyTransformer("hgetall", function (result) {
|
|
291
293
|
if (Array.isArray(result)) {
|
|
292
294
|
const obj = {};
|
|
@@ -297,17 +299,6 @@ Command.setReplyTransformer("hgetall", function (result) {
|
|
|
297
299
|
}
|
|
298
300
|
return result;
|
|
299
301
|
});
|
|
300
|
-
Command.setArgumentTransformer("hset", function (args) {
|
|
301
|
-
if (args.length === 2) {
|
|
302
|
-
if (typeof Map !== "undefined" && args[1] instanceof Map) {
|
|
303
|
-
return [args[0]].concat(utils_1.convertMapToArray(args[1]));
|
|
304
|
-
}
|
|
305
|
-
if (typeof args[1] === "object" && args[1] !== null) {
|
|
306
|
-
return [args[0]].concat(utils_1.convertObjectToArray(args[1]));
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
return args;
|
|
310
|
-
});
|
|
311
302
|
class MixedBuffers {
|
|
312
303
|
constructor() {
|
|
313
304
|
this.length = 0;
|
|
@@ -78,6 +78,9 @@ class SentinelConnector extends AbstractConnector_1.default {
|
|
|
78
78
|
else {
|
|
79
79
|
this.stream = net_1.createConnection(resolved);
|
|
80
80
|
}
|
|
81
|
+
this.stream.once("error", (err) => {
|
|
82
|
+
this.firstError = err;
|
|
83
|
+
});
|
|
81
84
|
this.sentinelIterator.reset(true);
|
|
82
85
|
resolve(this.stream);
|
|
83
86
|
}
|
package/built/pipeline.js
CHANGED
|
@@ -27,7 +27,8 @@ function generateMultiWithNodes(redis, keys) {
|
|
|
27
27
|
function Pipeline(redis) {
|
|
28
28
|
commander_1.default.call(this);
|
|
29
29
|
this.redis = redis;
|
|
30
|
-
this.isCluster =
|
|
30
|
+
this.isCluster =
|
|
31
|
+
this.redis.constructor.name === "Cluster" || this.redis.isCluster;
|
|
31
32
|
this.isPipeline = true;
|
|
32
33
|
this.options = redis.options;
|
|
33
34
|
this._queue = [];
|
package/built/redis/index.js
CHANGED
|
@@ -320,11 +320,22 @@ Redis.prototype.connect = function (callback) {
|
|
|
320
320
|
});
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
|
+
else if (stream.destroyed) {
|
|
324
|
+
const firstError = _this.connector.firstError;
|
|
325
|
+
if (firstError) {
|
|
326
|
+
process.nextTick(() => {
|
|
327
|
+
eventHandler.errorHandler(_this)(firstError);
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
process.nextTick(eventHandler.closeHandler(_this));
|
|
331
|
+
}
|
|
323
332
|
else {
|
|
324
333
|
process.nextTick(eventHandler.connectHandler(_this));
|
|
325
334
|
}
|
|
326
|
-
stream.
|
|
327
|
-
|
|
335
|
+
if (!stream.destroyed) {
|
|
336
|
+
stream.once("error", eventHandler.errorHandler(_this));
|
|
337
|
+
stream.once("close", eventHandler.closeHandler(_this));
|
|
338
|
+
}
|
|
328
339
|
if (options.noDelay) {
|
|
329
340
|
stream.setNoDelay(true);
|
|
330
341
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ioredis",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.24.2",
|
|
4
4
|
"description": "A robust, performance-focused and full-featured Redis client for Node.js.",
|
|
5
5
|
"main": "built/index.js",
|
|
6
6
|
"files": [
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"cluster-key-slot": "^1.1.0",
|
|
37
|
-
"debug": "^4.
|
|
37
|
+
"debug": "^4.3.1",
|
|
38
38
|
"denque": "^1.1.0",
|
|
39
39
|
"lodash.defaults": "^4.2.0",
|
|
40
40
|
"lodash.flatten": "^4.4.0",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"redis-commands": "1.7.0",
|
|
43
43
|
"redis-errors": "^1.2.0",
|
|
44
44
|
"redis-parser": "^3.0.0",
|
|
45
|
-
"standard-as-callback": "^2.0
|
|
45
|
+
"standard-as-callback": "^2.1.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@semantic-release/changelog": "^5.0.1",
|