ioredis 4.28.1 → 4.28.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 +9 -0
- package/README.md +12 -6
- package/built/autoPipelining.js +5 -1
- package/built/pipeline.js +16 -7
- package/built/utils/index.js +3 -3
- package/package.json +1 -1
package/Changelog.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## [4.28.2](https://github.com/luin/ioredis/compare/v4.28.1...v4.28.2) (2021-12-01)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* add Redis campaign ([#1475](https://github.com/luin/ioredis/issues/1475)) ([3f3d8e9](https://github.com/luin/ioredis/commit/3f3d8e9eb868f4e58bb63926d3b683d9892835f2))
|
|
7
|
+
* fix a memory leak with autopipelining. ([#1470](https://github.com/luin/ioredis/issues/1470)) ([f5d8b73](https://github.com/luin/ioredis/commit/f5d8b73c747a0db5cb36e83e6fe022a19a544bd2))
|
|
8
|
+
* unhandled Promise rejections in pipeline.exec [skip ci] ([#1466](https://github.com/luin/ioredis/issues/1466)) ([e5615da](https://github.com/luin/ioredis/commit/e5615da8786956df08a9b33b6cd4dd31e6eaa759))
|
|
9
|
+
|
|
1
10
|
## [4.28.1](https://github.com/luin/ioredis/compare/v4.28.0...v4.28.1) (2021-11-23)
|
|
2
11
|
|
|
3
12
|
|
package/README.md
CHANGED
|
@@ -45,15 +45,23 @@ used in the world's biggest online commerce company [Alibaba](http://www.alibaba
|
|
|
45
45
|
|
|
46
46
|
# Sponsors
|
|
47
47
|
|
|
48
|
-
<a href="https://github.com/sponsors/luin">Become a sponsor!</a>
|
|
49
|
-
|
|
50
48
|
### Upstash: Serverless Database for Redis
|
|
51
49
|
|
|
52
50
|
<a href="https://upstash.com/?utm_source=ioredis"><img align="right" width="320" src="resources/upstash.png" alt="Upstash"></a>
|
|
53
51
|
|
|
54
52
|
Upstash is a Serverless Database with Redis/REST API and durable storage. It is the perfect database for your applications thanks to its per request pricing and low latency data.
|
|
55
53
|
|
|
56
|
-
[Start for free in 30 seconds!
|
|
54
|
+
[Start for free in 30 seconds!](https://upstash.com/?utm_source=ioredis)
|
|
55
|
+
|
|
56
|
+
<br clear="both"/>
|
|
57
|
+
|
|
58
|
+
### Redis Cloud: From the creators of Redis
|
|
59
|
+
|
|
60
|
+
<a href="https://redis.info/ioredis-tryfree"><img align="right" width="320" src="resources/redis-tryfree.png" alt="redis-tryfree"></a>
|
|
61
|
+
|
|
62
|
+
Experience the best Redis. For a limited time, sign up to Redis Enterprise Cloud and use **MATRIX200** to get $200 credits, and a chance to win a Tesla!
|
|
63
|
+
|
|
64
|
+
[Sign Up Now!](https://redis.info/ioredis-tryfree)
|
|
57
65
|
|
|
58
66
|
<br clear="both"/>
|
|
59
67
|
|
|
@@ -74,9 +82,7 @@ Medis starts with all the basic features you need:
|
|
|
74
82
|
|
|
75
83
|
[Medis 1 is open sourced on GitHub](https://github.com/luin/medis)
|
|
76
84
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
<a href="http://bit.ly/kuber-ios"><img src="resources/kuber.png" alt="Download on the App Store"></a>
|
|
85
|
+
<br clear="both"/>
|
|
80
86
|
|
|
81
87
|
<hr>
|
|
82
88
|
|
package/built/autoPipelining.js
CHANGED
|
@@ -42,6 +42,10 @@ function executeAutoPipeline(client, slotKey) {
|
|
|
42
42
|
const pipeline = client._autoPipelines.get(slotKey);
|
|
43
43
|
client._autoPipelines.delete(slotKey);
|
|
44
44
|
const callbacks = pipeline[exports.kCallbacks];
|
|
45
|
+
// Stop keeping a reference to callbacks immediately after the callbacks stop being used.
|
|
46
|
+
// This allows the GC to reclaim objects referenced by callbacks, especially with 16384 slots
|
|
47
|
+
// in Redis.Cluster
|
|
48
|
+
pipeline[exports.kCallbacks] = null;
|
|
45
49
|
// Perform the call
|
|
46
50
|
pipeline.exec(function (err, results) {
|
|
47
51
|
client._runningAutoPipelines.delete(slotKey);
|
|
@@ -139,7 +143,7 @@ function executeWithAutoPipelining(client, functionName, commandName, args, call
|
|
|
139
143
|
*/
|
|
140
144
|
setImmediate(executeAutoPipeline, client, slotKey);
|
|
141
145
|
}
|
|
142
|
-
// Create the promise which will execute the
|
|
146
|
+
// Create the promise which will execute the command in the pipeline.
|
|
143
147
|
const autoPipelinePromise = new CustomPromise(function (resolve, reject) {
|
|
144
148
|
pipeline[exports.kCallbacks].push(function (err, value) {
|
|
145
149
|
if (err) {
|
package/built/pipeline.js
CHANGED
|
@@ -213,6 +213,12 @@ Pipeline.prototype.execBuffer = util_1.deprecate(function () {
|
|
|
213
213
|
}
|
|
214
214
|
return execBuffer.apply(this, arguments);
|
|
215
215
|
}, "Pipeline#execBuffer: Use Pipeline#exec instead");
|
|
216
|
+
// NOTE: To avoid an unhandled promise rejection, this will unconditionally always return this.promise,
|
|
217
|
+
// which always has the rejection handled by standard-as-callback
|
|
218
|
+
// adding the provided rejection callback.
|
|
219
|
+
//
|
|
220
|
+
// If a different promise instance were returned, that promise would cause its own unhandled promise rejection
|
|
221
|
+
// errors, even if that promise unconditionally resolved to **the resolved value of** this.promise.
|
|
216
222
|
Pipeline.prototype.exec = function (callback) {
|
|
217
223
|
// Wait for the cluster to be connected, since we need nodes information before continuing
|
|
218
224
|
if (this.isCluster && !this.redis.slots.length) {
|
|
@@ -286,16 +292,18 @@ Pipeline.prototype.exec = function (callback) {
|
|
|
286
292
|
}
|
|
287
293
|
// In cluster mode, always load scripts before running the pipeline
|
|
288
294
|
if (this.isCluster) {
|
|
289
|
-
|
|
295
|
+
pMap(scripts, (script) => _this.redis.script("load", script.lua), {
|
|
290
296
|
concurrency: 10,
|
|
291
|
-
})
|
|
297
|
+
})
|
|
298
|
+
.then(function () {
|
|
292
299
|
for (let i = 0; i < scripts.length; i++) {
|
|
293
300
|
_this.redis._addedScriptHashes[scripts[i].sha] = true;
|
|
294
301
|
}
|
|
295
|
-
|
|
296
|
-
|
|
302
|
+
})
|
|
303
|
+
.then(execPipeline, this.reject);
|
|
304
|
+
return this.promise;
|
|
297
305
|
}
|
|
298
|
-
|
|
306
|
+
this.redis
|
|
299
307
|
.script("exists", scripts.map(({ sha }) => sha))
|
|
300
308
|
.then(function (results) {
|
|
301
309
|
const pending = [];
|
|
@@ -313,8 +321,9 @@ Pipeline.prototype.exec = function (callback) {
|
|
|
313
321
|
for (let i = 0; i < scripts.length; i++) {
|
|
314
322
|
_this.redis._addedScriptHashes[scripts[i].sha] = true;
|
|
315
323
|
}
|
|
316
|
-
|
|
317
|
-
|
|
324
|
+
})
|
|
325
|
+
.then(execPipeline, this.reject);
|
|
326
|
+
return this.promise;
|
|
318
327
|
function execPipeline() {
|
|
319
328
|
let data = "";
|
|
320
329
|
let buffers;
|
package/built/utils/index.js
CHANGED
|
@@ -97,7 +97,7 @@ function wrapMultiResult(arr) {
|
|
|
97
97
|
}
|
|
98
98
|
exports.wrapMultiResult = wrapMultiResult;
|
|
99
99
|
/**
|
|
100
|
-
* Detect the argument is a int
|
|
100
|
+
* Detect if the argument is a int
|
|
101
101
|
*
|
|
102
102
|
* @param {string} value
|
|
103
103
|
* @return {boolean} Whether the value is a int
|
|
@@ -174,7 +174,7 @@ exports.timeout = timeout;
|
|
|
174
174
|
*/
|
|
175
175
|
function convertObjectToArray(obj) {
|
|
176
176
|
const result = [];
|
|
177
|
-
const keys = Object.keys(obj);
|
|
177
|
+
const keys = Object.keys(obj); // Object.entries requires node 7+
|
|
178
178
|
for (let i = 0, l = keys.length; i < l; i++) {
|
|
179
179
|
result.push(keys[i], obj[keys[i]]);
|
|
180
180
|
}
|
|
@@ -188,7 +188,7 @@ exports.convertObjectToArray = convertObjectToArray;
|
|
|
188
188
|
* @return {array}
|
|
189
189
|
* @example
|
|
190
190
|
* ```js
|
|
191
|
-
* >
|
|
191
|
+
* > convertMapToArray(new Map([[1, '2']]))
|
|
192
192
|
* [1, '2']
|
|
193
193
|
* ```
|
|
194
194
|
*/
|