ioredis 4.27.1 → 4.27.5
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/built/autoPipelining.js +6 -5
- package/built/cluster/index.js +6 -3
- package/built/command.js +1 -1
- package/built/commander.js +29 -18
- package/built/connectors/SentinelConnector/index.js +3 -0
- package/built/pipeline.js +4 -0
- package/built/redis/RedisOptions.js +1 -0
- package/built/redis/index.js +5 -0
- package/package.json +1 -1
package/Changelog.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## [4.27.5](https://github.com/luin/ioredis/compare/v4.27.4...v4.27.5) (2021-06-05)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **SENTINEL:** actively failover detection under an option ([#1363](https://github.com/luin/ioredis/issues/1363)) ([f02e383](https://github.com/luin/ioredis/commit/f02e383996310adaefc2b4c40d946b76e450e5c7))
|
|
7
|
+
|
|
8
|
+
## [4.27.4](https://github.com/luin/ioredis/compare/v4.27.3...v4.27.4) (2021-06-04)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Performance Improvements
|
|
12
|
+
|
|
13
|
+
* Serialize error stack only when needed ([#1359](https://github.com/luin/ioredis/issues/1359)) ([62b6a64](https://github.com/luin/ioredis/commit/62b6a648910eccc3d83a3acd2db873704fd2080a))
|
|
14
|
+
|
|
15
|
+
## [4.27.3](https://github.com/luin/ioredis/compare/v4.27.2...v4.27.3) (2021-05-22)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* autopipeling for buffer function ([#1231](https://github.com/luin/ioredis/issues/1231)) ([abd9a82](https://github.com/luin/ioredis/commit/abd9a82433ad67b91a4bddb45aff8da2e20d45e8))
|
|
21
|
+
|
|
22
|
+
## [4.27.2](https://github.com/luin/ioredis/compare/v4.27.1...v4.27.2) (2021-05-04)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* **cluster:** avoid ClusterAllFailedError in certain cases ([aa9c5b1](https://github.com/luin/ioredis/commit/aa9c5b1fee5daa24f35b3ff0d3556ecfb86db251)), closes [#1330](https://github.com/luin/ioredis/issues/1330)
|
|
28
|
+
|
|
1
29
|
## [4.27.1](https://github.com/luin/ioredis/compare/v4.27.0...v4.27.1) (2021-04-24)
|
|
2
30
|
|
|
3
31
|
|
package/built/autoPipelining.js
CHANGED
|
@@ -61,14 +61,15 @@ function executeAutoPipeline(client, slotKey) {
|
|
|
61
61
|
}
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
|
-
function shouldUseAutoPipelining(client, commandName) {
|
|
65
|
-
return (
|
|
64
|
+
function shouldUseAutoPipelining(client, functionName, commandName) {
|
|
65
|
+
return (functionName &&
|
|
66
|
+
client.options.enableAutoPipelining &&
|
|
66
67
|
!client.isPipeline &&
|
|
67
68
|
!exports.notAllowedAutoPipelineCommands.includes(commandName) &&
|
|
68
69
|
!client.options.autoPipeliningIgnoredCommands.includes(commandName));
|
|
69
70
|
}
|
|
70
71
|
exports.shouldUseAutoPipelining = shouldUseAutoPipelining;
|
|
71
|
-
function executeWithAutoPipelining(client, commandName, args, callback) {
|
|
72
|
+
function executeWithAutoPipelining(client, functionName, commandName, args, callback) {
|
|
72
73
|
const CustomPromise = PromiseContainer.get();
|
|
73
74
|
// On cluster mode let's wait for slots to be available
|
|
74
75
|
if (client.isCluster && !client.slots.length) {
|
|
@@ -78,7 +79,7 @@ function executeWithAutoPipelining(client, commandName, args, callback) {
|
|
|
78
79
|
reject(err);
|
|
79
80
|
return;
|
|
80
81
|
}
|
|
81
|
-
executeWithAutoPipelining(client, commandName, args, callback).then(resolve, reject);
|
|
82
|
+
executeWithAutoPipelining(client, functionName, commandName, args, callback).then(resolve, reject);
|
|
82
83
|
});
|
|
83
84
|
});
|
|
84
85
|
}
|
|
@@ -112,7 +113,7 @@ function executeWithAutoPipelining(client, commandName, args, callback) {
|
|
|
112
113
|
}
|
|
113
114
|
resolve(value);
|
|
114
115
|
});
|
|
115
|
-
pipeline[
|
|
116
|
+
pipeline[functionName](...args);
|
|
116
117
|
});
|
|
117
118
|
return standard_as_callback_1.default(autoPipelinePromise, callback);
|
|
118
119
|
}
|
package/built/cluster/index.js
CHANGED
|
@@ -185,7 +185,12 @@ 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()
|
|
188
|
+
this.refreshSlotsCache(function (err) {
|
|
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));
|
|
189
194
|
this.subscriber.start();
|
|
190
195
|
})
|
|
191
196
|
.catch((err) => {
|
|
@@ -385,8 +390,6 @@ class Cluster extends events_1.EventEmitter {
|
|
|
385
390
|
function tryNode(index) {
|
|
386
391
|
if (index === nodes.length) {
|
|
387
392
|
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([]);
|
|
390
393
|
return wrapper(error);
|
|
391
394
|
}
|
|
392
395
|
const node = nodes[index];
|
package/built/command.js
CHANGED
|
@@ -101,7 +101,7 @@ class Command {
|
|
|
101
101
|
this.resolve = this._convertValue(resolve);
|
|
102
102
|
if (this.errorStack) {
|
|
103
103
|
this.reject = (err) => {
|
|
104
|
-
reject(utils_1.optimizeErrorStack(err, this.errorStack, __dirname));
|
|
104
|
+
reject(utils_1.optimizeErrorStack(err, this.errorStack.stack, __dirname));
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
107
|
else {
|
package/built/commander.js
CHANGED
|
@@ -23,6 +23,7 @@ function Commander() {
|
|
|
23
23
|
showFriendlyErrorStack: false,
|
|
24
24
|
});
|
|
25
25
|
this.scriptsSet = {};
|
|
26
|
+
this.addedBuiltinSet = new Set();
|
|
26
27
|
}
|
|
27
28
|
exports.default = Commander;
|
|
28
29
|
const commands = require("redis-commands").list.filter(function (command) {
|
|
@@ -47,16 +48,28 @@ Commander.prototype.getBuiltinCommands = function () {
|
|
|
47
48
|
*/
|
|
48
49
|
Commander.prototype.createBuiltinCommand = function (commandName) {
|
|
49
50
|
return {
|
|
50
|
-
string: generateFunction(commandName, "utf8"),
|
|
51
|
-
buffer: generateFunction(commandName, null),
|
|
51
|
+
string: generateFunction(null, commandName, "utf8"),
|
|
52
|
+
buffer: generateFunction(null, commandName, null),
|
|
52
53
|
};
|
|
53
54
|
};
|
|
55
|
+
/**
|
|
56
|
+
* Create add builtin command
|
|
57
|
+
*
|
|
58
|
+
* @param {string} commandName - command name
|
|
59
|
+
* @return {object} functions
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
Commander.prototype.addBuiltinCommand = function (commandName) {
|
|
63
|
+
this.addedBuiltinSet.add(commandName);
|
|
64
|
+
this[commandName] = generateFunction(commandName, commandName, "utf8");
|
|
65
|
+
this[commandName + "Buffer"] = generateFunction(commandName + "Buffer", commandName, null);
|
|
66
|
+
};
|
|
54
67
|
commands.forEach(function (commandName) {
|
|
55
|
-
Commander.prototype[commandName] = generateFunction(commandName, "utf8");
|
|
56
|
-
Commander.prototype[commandName + "Buffer"] = generateFunction(commandName, null);
|
|
68
|
+
Commander.prototype[commandName] = generateFunction(commandName, commandName, "utf8");
|
|
69
|
+
Commander.prototype[commandName + "Buffer"] = generateFunction(commandName + "Buffer", commandName, null);
|
|
57
70
|
});
|
|
58
|
-
Commander.prototype.call = generateFunction("utf8");
|
|
59
|
-
Commander.prototype.callBuffer = generateFunction(null);
|
|
71
|
+
Commander.prototype.call = generateFunction("call", "utf8");
|
|
72
|
+
Commander.prototype.callBuffer = generateFunction("callBuffer", null);
|
|
60
73
|
// eslint-disable-next-line @typescript-eslint/camelcase
|
|
61
74
|
Commander.prototype.send_command = Commander.prototype.call;
|
|
62
75
|
/**
|
|
@@ -72,8 +85,8 @@ Commander.prototype.send_command = Commander.prototype.call;
|
|
|
72
85
|
Commander.prototype.defineCommand = function (name, definition) {
|
|
73
86
|
const script = new script_1.default(definition.lua, definition.numberOfKeys, this.options.keyPrefix, definition.readOnly);
|
|
74
87
|
this.scriptsSet[name] = script;
|
|
75
|
-
this[name] = generateScriptingFunction(name, script, "utf8");
|
|
76
|
-
this[name + "Buffer"] = generateScriptingFunction(name, script, null);
|
|
88
|
+
this[name] = generateScriptingFunction(name, name, script, "utf8");
|
|
89
|
+
this[name + "Buffer"] = generateScriptingFunction(name + "Buffer", name, script, null);
|
|
77
90
|
};
|
|
78
91
|
/**
|
|
79
92
|
* Send a command
|
|
@@ -82,7 +95,7 @@ Commander.prototype.defineCommand = function (name, definition) {
|
|
|
82
95
|
* @public
|
|
83
96
|
*/
|
|
84
97
|
Commander.prototype.sendCommand = function () { };
|
|
85
|
-
function generateFunction(_commandName, _encoding) {
|
|
98
|
+
function generateFunction(functionName, _commandName, _encoding) {
|
|
86
99
|
if (typeof _encoding === "undefined") {
|
|
87
100
|
_encoding = _commandName;
|
|
88
101
|
_commandName = null;
|
|
@@ -97,9 +110,7 @@ function generateFunction(_commandName, _encoding) {
|
|
|
97
110
|
callback = undefined;
|
|
98
111
|
}
|
|
99
112
|
const options = {
|
|
100
|
-
errorStack: this.options.showFriendlyErrorStack
|
|
101
|
-
? new Error().stack
|
|
102
|
-
: undefined,
|
|
113
|
+
errorStack: this.options.showFriendlyErrorStack ? new Error() : undefined,
|
|
103
114
|
keyPrefix: this.options.keyPrefix,
|
|
104
115
|
replyEncoding: _encoding,
|
|
105
116
|
};
|
|
@@ -107,14 +118,14 @@ function generateFunction(_commandName, _encoding) {
|
|
|
107
118
|
return standard_as_callback_1.default(PromiseContainer.get().reject(new Error(DROP_BUFFER_SUPPORT_ERROR)), callback);
|
|
108
119
|
}
|
|
109
120
|
// No auto pipeline, use regular command sending
|
|
110
|
-
if (!autoPipelining_1.shouldUseAutoPipelining(this, commandName)) {
|
|
121
|
+
if (!autoPipelining_1.shouldUseAutoPipelining(this, functionName, commandName)) {
|
|
111
122
|
return this.sendCommand(new command_1.default(commandName, args, options, callback));
|
|
112
123
|
}
|
|
113
124
|
// Create a new pipeline and make sure it's scheduled
|
|
114
|
-
return autoPipelining_1.executeWithAutoPipelining(this, commandName, args, callback);
|
|
125
|
+
return autoPipelining_1.executeWithAutoPipelining(this, functionName, commandName, args, callback);
|
|
115
126
|
};
|
|
116
127
|
}
|
|
117
|
-
function generateScriptingFunction(
|
|
128
|
+
function generateScriptingFunction(functionName, commandName, script, encoding) {
|
|
118
129
|
return function () {
|
|
119
130
|
let length = arguments.length;
|
|
120
131
|
const lastArgIndex = length - 1;
|
|
@@ -140,13 +151,13 @@ function generateScriptingFunction(name, script, encoding) {
|
|
|
140
151
|
options = { replyEncoding: encoding };
|
|
141
152
|
}
|
|
142
153
|
if (this.options.showFriendlyErrorStack) {
|
|
143
|
-
options.errorStack = new Error()
|
|
154
|
+
options.errorStack = new Error();
|
|
144
155
|
}
|
|
145
156
|
// No auto pipeline, use regular command sending
|
|
146
|
-
if (!autoPipelining_1.shouldUseAutoPipelining(this,
|
|
157
|
+
if (!autoPipelining_1.shouldUseAutoPipelining(this, functionName, commandName)) {
|
|
147
158
|
return script.execute(this, args, options, callback);
|
|
148
159
|
}
|
|
149
160
|
// Create a new pipeline and make sure it's scheduled
|
|
150
|
-
return autoPipelining_1.executeWithAutoPipelining(this,
|
|
161
|
+
return autoPipelining_1.executeWithAutoPipelining(this, functionName, commandName, args, callback);
|
|
151
162
|
};
|
|
152
163
|
}
|
|
@@ -205,6 +205,9 @@ class SentinelConnector extends AbstractConnector_1.default {
|
|
|
205
205
|
initFailoverDetector() {
|
|
206
206
|
var _a;
|
|
207
207
|
return __awaiter(this, void 0, void 0, function* () {
|
|
208
|
+
if (!this.options.failoverDetector) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
208
211
|
// Move the current sentinel to the first position
|
|
209
212
|
this.sentinelIterator.reset(true);
|
|
210
213
|
const sentinels = [];
|
package/built/pipeline.js
CHANGED
|
@@ -41,6 +41,10 @@ function Pipeline(redis) {
|
|
|
41
41
|
this[name] = redis[name];
|
|
42
42
|
this[name + "Buffer"] = redis[name + "Buffer"];
|
|
43
43
|
});
|
|
44
|
+
redis.addedBuiltinSet.forEach((name) => {
|
|
45
|
+
this[name] = redis[name];
|
|
46
|
+
this[name + "Buffer"] = redis[name + "Buffer"];
|
|
47
|
+
});
|
|
44
48
|
const Promise = PromiseContainer.get();
|
|
45
49
|
this.promise = new Promise((resolve, reject) => {
|
|
46
50
|
this.resolve = resolve;
|
package/built/redis/index.js
CHANGED
|
@@ -93,6 +93,11 @@ const debug = utils_1.Debug("redis");
|
|
|
93
93
|
* @param {NatMap} [options.natMap=null] NAT map for sentinel connector.
|
|
94
94
|
* @param {boolean} [options.updateSentinels=true] - Update the given `sentinels` list with new IP
|
|
95
95
|
* addresses when communicating with existing sentinels.
|
|
96
|
+
* @param {boolean} [options.failoverDetector=false] - Detect failover actively by subscribing to the
|
|
97
|
+
* related channels. With this option disabled, ioredis is still able to detect failovers because Redis
|
|
98
|
+
* Sentinel will disconnect all clients whenever a failover happens, so ioredis will reconnect to the new
|
|
99
|
+
* master. This option is useful when you want to detect failover quicker, but it will create more TCP
|
|
100
|
+
* connections to Redis servers in order to subscribe to related channels.
|
|
96
101
|
* @param {boolean} [options.enableAutoPipelining=false] - When enabled, all commands issued during an event loop
|
|
97
102
|
* iteration are automatically wrapped in a pipeline and sent to the server at the same time.
|
|
98
103
|
* This can dramatically improve performance.
|