ioredis 4.23.1 → 4.24.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog.md +28 -0
- package/README.md +64 -22
- package/built/autoPipelining.js +1 -0
- package/built/cluster/ClusterOptions.js +2 -0
- package/built/cluster/index.js +14 -8
- package/built/cluster/util.js +1 -0
- package/built/command.js +6 -15
- package/built/connectors/SentinelConnector/index.js +4 -0
- package/built/connectors/StandaloneConnector.js +4 -0
- package/built/connectors/index.js +1 -0
- package/built/errors/index.js +1 -0
- package/built/index.js +9 -8
- package/built/pipeline.js +15 -4
- package/built/promiseContainer.js +1 -0
- package/built/redis/RedisOptions.js +1 -0
- package/built/redis/event_handler.js +1 -0
- package/built/redis/index.js +13 -2
- package/built/transaction.js +1 -0
- package/built/utils/debug.js +1 -0
- package/built/utils/index.js +4 -3
- package/built/utils/lodash.js +1 -0
- package/package.json +3 -3
package/Changelog.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## [4.24.3](https://github.com/luin/ioredis/compare/v4.24.2...v4.24.3) (2021-03-21)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* support parallel script execution in pipelines ([#1304](https://github.com/luin/ioredis/issues/1304)) ([c917719](https://github.com/luin/ioredis/commit/c91771997e5e3a0196d380522b4750de9e84cc9b))
|
|
7
|
+
|
|
8
|
+
## [4.24.2](https://github.com/luin/ioredis/compare/v4.24.1...v4.24.2) (2021-03-14)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* properly handle instant stream errors ([#1299](https://github.com/luin/ioredis/issues/1299)) ([0327ef5](https://github.com/luin/ioredis/commit/0327ef5a57481042d3f7d306917f55ef04f3a6cc))
|
|
14
|
+
|
|
15
|
+
## [4.24.1](https://github.com/luin/ioredis/compare/v4.24.0...v4.24.1) (2021-03-14)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **cluster:** reconnect when failing to refresh slots cache for all nodes ([8524eea](https://github.com/luin/ioredis/commit/8524eeaedaa2542f119f2b65ab8e2f15644b474e))
|
|
21
|
+
|
|
22
|
+
# [4.24.0](https://github.com/luin/ioredis/compare/v4.23.1...v4.24.0) (2021-03-14)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* **cluster:** support retrying MOVED with a delay ([#1254](https://github.com/luin/ioredis/issues/1254)) ([8599981](https://github.com/luin/ioredis/commit/8599981141e8357f5ae2706fffb55010490bf002))
|
|
28
|
+
|
|
1
29
|
## [4.23.1](https://github.com/luin/ioredis/compare/v4.23.0...v4.23.1) (2021-03-14)
|
|
2
30
|
|
|
3
31
|
|
package/README.md
CHANGED
|
@@ -148,50 +148,88 @@ See [API Documentation](API.md#new_Redis) for all available options.
|
|
|
148
148
|
|
|
149
149
|
## Pub/Sub
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
and publishes to that channel with the other:
|
|
151
|
+
Redis provides several commands for developers to implement the [Publish–subscribe pattern](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern). There are two roles in this pattern: publisher and subscriber. Publishers are not programmed to send their messages to specific subscribers. Rather, published messages are characterized into channels, without knowledge of what (if any) subscribers there may be.
|
|
152
|
+
|
|
153
|
+
By leveraging Node.js's built-in events module, ioredis makes pub/sub very straightforward to use. Below is a simple example that consists of two files, one is publisher.js that publishes messages to a channel, the other is subscriber.js that listens for messages on specific channels.
|
|
155
154
|
|
|
156
155
|
```javascript
|
|
156
|
+
// publisher.js
|
|
157
|
+
|
|
157
158
|
const Redis = require("ioredis");
|
|
158
159
|
const redis = new Redis();
|
|
159
|
-
const pub = new Redis();
|
|
160
|
-
redis.subscribe("news", "music", (err, count) => {
|
|
161
|
-
// Now we are subscribed to both the 'news' and 'music' channels.
|
|
162
|
-
// `count` represents the number of channels we are currently subscribed to.
|
|
163
160
|
|
|
164
|
-
|
|
165
|
-
|
|
161
|
+
setInterval(() => {
|
|
162
|
+
const message = { foo: Math.random() };
|
|
163
|
+
// Publish to my-channel-1 or my-channel-2 randomly.
|
|
164
|
+
const channel = `my-channel-${1 + Math.round(Math.random())}`;
|
|
165
|
+
|
|
166
|
+
// Message can be either a string or a buffer
|
|
167
|
+
redis.publish(channel, JSON.stringify(message));
|
|
168
|
+
console.log("Published %s to %s", message, channel);
|
|
169
|
+
}, 1000);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```javascript
|
|
173
|
+
// subscriber.js
|
|
174
|
+
|
|
175
|
+
const Redis = require("ioredis");
|
|
176
|
+
const redis = new Redis();
|
|
177
|
+
|
|
178
|
+
redis.subscribe("my-channel-1", "my-channel-2", (err, count) => {
|
|
179
|
+
if (err) {
|
|
180
|
+
// Just like other commands, subscribe() can fail for some reasons,
|
|
181
|
+
// ex network issues.
|
|
182
|
+
console.error("Failed to subscribe: %s", err.message);
|
|
183
|
+
} else {
|
|
184
|
+
// `count` represents the number of channels this client are currently subscribed to.
|
|
185
|
+
console.log(
|
|
186
|
+
`Subscribed successfully! This client is currently subscribed to ${count} channels.`
|
|
187
|
+
);
|
|
188
|
+
}
|
|
166
189
|
});
|
|
167
190
|
|
|
168
191
|
redis.on("message", (channel, message) => {
|
|
169
|
-
|
|
170
|
-
// Receive message Hello again! from channel music
|
|
171
|
-
console.log("Receive message %s from channel %s", message, channel);
|
|
192
|
+
console.log(`Received ${message} from ${channel}`);
|
|
172
193
|
});
|
|
173
194
|
|
|
174
195
|
// There's also an event called 'messageBuffer', which is the same as 'message' except
|
|
175
196
|
// it returns buffers instead of strings.
|
|
197
|
+
// It's useful when the messages are binary data.
|
|
176
198
|
redis.on("messageBuffer", (channel, message) => {
|
|
177
199
|
// Both `channel` and `message` are buffers.
|
|
200
|
+
console.log(channel, message);
|
|
178
201
|
});
|
|
179
202
|
```
|
|
180
203
|
|
|
181
|
-
`
|
|
204
|
+
It worth noticing that a connection (aka `Redis` instance) can't play both roles together. More specifically, when a client issues `subscribe()` or `psubscribe()`, it enters the "subscriber" mode. From that point, only commands that modify the subscription set are valid. Namely, they are: `subscribe`, `psubscribe`, `unsubscribe`, `punsubscribe`, `ping`, and `quit`. When the subscription set is empty (via `unsubscribe`/`punsubscribe`), the connection is put back into the regular mode.
|
|
205
|
+
|
|
206
|
+
If you want to do pub/sub in the same file/process, you should create a separate connection:
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
const Redis = require('ioredis');
|
|
210
|
+
const sub = new Redis();
|
|
211
|
+
const pub = new Redis();
|
|
212
|
+
|
|
213
|
+
sub.subscribe(/* ... */); // From now, `sub` enters the subscriber mode.
|
|
214
|
+
sub.on("message", /* ... */);
|
|
215
|
+
|
|
216
|
+
setInterval(() => {
|
|
217
|
+
// `pub` can be used to publish messages, or send other regular commands (e.g. `hgetall`)
|
|
218
|
+
// because it's not in the subscriber mode.
|
|
219
|
+
pub.publish(/* ... */);
|
|
220
|
+
}, 1000);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
`PSUBSCRIBE` is also supported in a similar way when you want to subscribe all channels whose name matches a pattern:
|
|
182
224
|
|
|
183
225
|
```javascript
|
|
184
226
|
redis.psubscribe("pat?ern", (err, count) => {});
|
|
227
|
+
|
|
228
|
+
// Event names are "pmessage"/"pmessageBuffer" instead of "message/messageBuffer".
|
|
185
229
|
redis.on("pmessage", (pattern, channel, message) => {});
|
|
186
230
|
redis.on("pmessageBuffer", (pattern, channel, message) => {});
|
|
187
231
|
```
|
|
188
232
|
|
|
189
|
-
When a client issues a SUBSCRIBE or PSUBSCRIBE, that connection is put into a "subscriber" mode.
|
|
190
|
-
At that point, only commands that modify the subscription set are valid.
|
|
191
|
-
When the subscription set is empty, the connection is put back into regular mode.
|
|
192
|
-
|
|
193
|
-
If you need to send regular commands to Redis while in subscriber mode, just open another connection.
|
|
194
|
-
|
|
195
233
|
## Handle Binary Data
|
|
196
234
|
|
|
197
235
|
Arguments can be buffers:
|
|
@@ -703,6 +741,7 @@ The Redis instance will emit some events about the state of the connection to th
|
|
|
703
741
|
| close | emits when an established Redis server connection has closed. |
|
|
704
742
|
| reconnecting | emits after `close` when a reconnection will be made. The argument of the event is the time (in ms) before reconnecting. |
|
|
705
743
|
| end | emits after `close` when no more reconnections will be made, or the connection is failed to establish. |
|
|
744
|
+
| wait | emits when `lazyConnect` is set and will wait for the first command to be called before connecting. |
|
|
706
745
|
|
|
707
746
|
You can also check out the `Redis#status` property to get the current connection status.
|
|
708
747
|
|
|
@@ -889,9 +928,12 @@ cluster.get("foo", (err, res) => {
|
|
|
889
928
|
will resend the commands after the specified time (in ms).
|
|
890
929
|
- `retryDelayOnTryAgain`: If this option is a number (by default, it is `100`), the client
|
|
891
930
|
will resend the commands rejected with `TRYAGAIN` error after the specified time (in ms).
|
|
931
|
+
- `retryDelayOnMoved`: By default, this value is `0` (in ms), which means when a `MOVED` error is received, the client will resend
|
|
932
|
+
the command instantly to the node returned together with the `MOVED` error. However, sometimes it takes time for a cluster to become
|
|
933
|
+
state stabilized after a failover, so adding a delay before resending can prevent a ping pong effect.
|
|
892
934
|
- `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`)
|
|
935
|
+
- `slotsRefreshTimeout`: Milliseconds before a timeout occurs while refreshing slots from the cluster (default `1000`).
|
|
936
|
+
- `slotsRefreshInterval`: Milliseconds between every automatic slots refresh (default `5000`).
|
|
895
937
|
|
|
896
938
|
### Read-write splitting
|
|
897
939
|
|
package/built/autoPipelining.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeWithAutoPipelining = exports.shouldUseAutoPipelining = exports.notAllowedAutoPipelineCommands = exports.kCallbacks = exports.kExec = void 0;
|
|
3
4
|
const PromiseContainer = require("./promiseContainer");
|
|
4
5
|
const calculateSlot = require("cluster-key-slot");
|
|
5
6
|
const standard_as_callback_1 = require("standard-as-callback");
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_CLUSTER_OPTIONS = void 0;
|
|
3
4
|
const dns_1 = require("dns");
|
|
4
5
|
exports.DEFAULT_CLUSTER_OPTIONS = {
|
|
5
6
|
clusterRetryStrategy: (times) => Math.min(100 + times * 2, 2000),
|
|
@@ -7,6 +8,7 @@ exports.DEFAULT_CLUSTER_OPTIONS = {
|
|
|
7
8
|
enableReadyCheck: true,
|
|
8
9
|
scaleReads: "master",
|
|
9
10
|
maxRedirections: 16,
|
|
11
|
+
retryDelayOnMoved: 0,
|
|
10
12
|
retryDelayOnFailover: 100,
|
|
11
13
|
retryDelayOnClusterDown: 100,
|
|
12
14
|
retryDelayOnTryAgain: 100,
|
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/cluster/util.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.weightSrvRecords = exports.groupSrvRecords = exports.getUniqueHostnamesFromOptions = exports.normalizeNodeOptions = exports.nodeKeyToRedisOptions = exports.getNodeKey = void 0;
|
|
3
4
|
const utils_1 = require("../utils");
|
|
4
5
|
const net_1 = require("net");
|
|
5
6
|
function getNodeKey(node) {
|
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;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SentinelIterator = void 0;
|
|
3
4
|
const net_1 = require("net");
|
|
4
5
|
const utils_1 = require("../../utils");
|
|
5
6
|
const tls_1 = require("tls");
|
|
@@ -78,6 +79,9 @@ class SentinelConnector extends AbstractConnector_1.default {
|
|
|
78
79
|
else {
|
|
79
80
|
this.stream = net_1.createConnection(resolved);
|
|
80
81
|
}
|
|
82
|
+
this.stream.once("error", (err) => {
|
|
83
|
+
this.firstError = err;
|
|
84
|
+
});
|
|
81
85
|
this.sentinelIterator.reset(true);
|
|
82
86
|
resolve(this.stream);
|
|
83
87
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isIIpcConnectionOptions = void 0;
|
|
3
4
|
const net_1 = require("net");
|
|
4
5
|
const tls_1 = require("tls");
|
|
5
6
|
const utils_1 = require("../utils");
|
|
@@ -62,6 +63,9 @@ class StandaloneConnector extends AbstractConnector_1.default {
|
|
|
62
63
|
reject(err);
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
66
|
+
this.stream.once("error", (err) => {
|
|
67
|
+
this.firstError = err;
|
|
68
|
+
});
|
|
65
69
|
resolve(this.stream);
|
|
66
70
|
});
|
|
67
71
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SentinelConnector = exports.StandaloneConnector = void 0;
|
|
3
4
|
const StandaloneConnector_1 = require("./StandaloneConnector");
|
|
4
5
|
exports.StandaloneConnector = StandaloneConnector_1.default;
|
|
5
6
|
const SentinelConnector_1 = require("./SentinelConnector");
|
package/built/errors/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MaxRetriesPerRequestError = void 0;
|
|
3
4
|
const MaxRetriesPerRequestError_1 = require("./MaxRetriesPerRequestError");
|
|
4
5
|
exports.MaxRetriesPerRequestError = MaxRetriesPerRequestError_1.default;
|
package/built/index.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.print = exports.ReplyError = void 0;
|
|
3
4
|
exports = module.exports = require("./redis").default;
|
|
4
5
|
var redis_1 = require("./redis");
|
|
5
|
-
exports
|
|
6
|
+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return redis_1.default; } });
|
|
6
7
|
var cluster_1 = require("./cluster");
|
|
7
|
-
exports
|
|
8
|
+
Object.defineProperty(exports, "Cluster", { enumerable: true, get: function () { return cluster_1.default; } });
|
|
8
9
|
var command_1 = require("./command");
|
|
9
|
-
exports
|
|
10
|
+
Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return command_1.default; } });
|
|
10
11
|
var ScanStream_1 = require("./ScanStream");
|
|
11
|
-
exports
|
|
12
|
+
Object.defineProperty(exports, "ScanStream", { enumerable: true, get: function () { return ScanStream_1.default; } });
|
|
12
13
|
var pipeline_1 = require("./pipeline");
|
|
13
|
-
exports
|
|
14
|
+
Object.defineProperty(exports, "Pipeline", { enumerable: true, get: function () { return pipeline_1.default; } });
|
|
14
15
|
var AbstractConnector_1 = require("./connectors/AbstractConnector");
|
|
15
|
-
exports
|
|
16
|
+
Object.defineProperty(exports, "AbstractConnector", { enumerable: true, get: function () { return AbstractConnector_1.default; } });
|
|
16
17
|
var SentinelConnector_1 = require("./connectors/SentinelConnector");
|
|
17
|
-
exports
|
|
18
|
-
exports
|
|
18
|
+
Object.defineProperty(exports, "SentinelConnector", { enumerable: true, get: function () { return SentinelConnector_1.default; } });
|
|
19
|
+
Object.defineProperty(exports, "SentinelIterator", { enumerable: true, get: function () { return SentinelConnector_1.SentinelIterator; } });
|
|
19
20
|
// No TS typings
|
|
20
21
|
exports.ReplyError = require("redis-errors").ReplyError;
|
|
21
22
|
const PromiseContainer = require("./promiseContainer");
|
package/built/pipeline.js
CHANGED
|
@@ -265,11 +265,12 @@ Pipeline.prototype.exec = function (callback) {
|
|
|
265
265
|
continue;
|
|
266
266
|
}
|
|
267
267
|
const script = this._shaToScript[item.args[0]];
|
|
268
|
-
if (!script ||
|
|
268
|
+
if (!script ||
|
|
269
|
+
this.redis._addedScriptHashes[script.sha] ||
|
|
270
|
+
scripts.includes(script)) {
|
|
269
271
|
continue;
|
|
270
272
|
}
|
|
271
273
|
scripts.push(script);
|
|
272
|
-
this.redis._addedScriptHashes[script.sha] = true;
|
|
273
274
|
}
|
|
274
275
|
const _this = this;
|
|
275
276
|
if (!scripts.length) {
|
|
@@ -279,7 +280,12 @@ Pipeline.prototype.exec = function (callback) {
|
|
|
279
280
|
if (this.isCluster) {
|
|
280
281
|
return pMap(scripts, (script) => _this.redis.script("load", script.lua), {
|
|
281
282
|
concurrency: 10,
|
|
282
|
-
}).then(
|
|
283
|
+
}).then(function () {
|
|
284
|
+
for (let i = 0; i < scripts.length; i++) {
|
|
285
|
+
_this.redis._addedScriptHashes[scripts[i].sha] = true;
|
|
286
|
+
}
|
|
287
|
+
return execPipeline();
|
|
288
|
+
});
|
|
283
289
|
}
|
|
284
290
|
return this.redis
|
|
285
291
|
.script("exists", scripts.map(({ sha }) => sha))
|
|
@@ -295,7 +301,12 @@ Pipeline.prototype.exec = function (callback) {
|
|
|
295
301
|
return _this.redis.script("load", script.lua);
|
|
296
302
|
}));
|
|
297
303
|
})
|
|
298
|
-
.then(
|
|
304
|
+
.then(function () {
|
|
305
|
+
for (let i = 0; i < scripts.length; i++) {
|
|
306
|
+
_this.redis._addedScriptHashes[scripts[i].sha] = true;
|
|
307
|
+
}
|
|
308
|
+
return execPipeline();
|
|
309
|
+
});
|
|
299
310
|
function execPipeline() {
|
|
300
311
|
let data = "";
|
|
301
312
|
let buffers;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readyHandler = exports.errorHandler = exports.closeHandler = exports.connectHandler = void 0;
|
|
3
4
|
const redis_errors_1 = require("redis-errors");
|
|
4
5
|
const command_1 = require("../command");
|
|
5
6
|
const errors_1 = require("../errors");
|
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/built/transaction.js
CHANGED
package/built/utils/debug.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.genRedactedString = exports.getStringValue = exports.MAX_ARGUMENT_LENGTH = void 0;
|
|
3
4
|
const debug_1 = require("debug");
|
|
4
5
|
const MAX_ARGUMENT_LENGTH = 200;
|
|
5
6
|
exports.MAX_ARGUMENT_LENGTH = MAX_ARGUMENT_LENGTH;
|
package/built/utils/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.flatten = exports.noop = exports.defaults = exports.Debug = exports.zipMap = exports.CONNECTION_CLOSED_ERROR_MSG = exports.shuffle = exports.sample = exports.parseURL = exports.optimizeErrorStack = exports.toArg = exports.convertMapToArray = exports.convertObjectToArray = exports.timeout = exports.packObject = exports.isInt = exports.wrapMultiResult = exports.convertBufferToString = exports.bufferEqual = void 0;
|
|
3
4
|
const url_1 = require("url");
|
|
4
5
|
const lodash_1 = require("./lodash");
|
|
5
|
-
exports
|
|
6
|
-
exports
|
|
7
|
-
exports
|
|
6
|
+
Object.defineProperty(exports, "defaults", { enumerable: true, get: function () { return lodash_1.defaults; } });
|
|
7
|
+
Object.defineProperty(exports, "noop", { enumerable: true, get: function () { return lodash_1.noop; } });
|
|
8
|
+
Object.defineProperty(exports, "flatten", { enumerable: true, get: function () { return lodash_1.flatten; } });
|
|
8
9
|
const debug_1 = require("./debug");
|
|
9
10
|
exports.Debug = debug_1.default;
|
|
10
11
|
/**
|
package/built/utils/lodash.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ioredis",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.24.3",
|
|
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",
|