@xnestjs/ioredis 0.2.0 → 0.3.0
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/cjs/redis-client.d.ts +39 -7
- package/cjs/redis-client.js +68 -9
- package/cjs/redis-client.js.map +1 -1
- package/cjs/redis-core.module.d.ts +2 -5
- package/cjs/redis-core.module.js +50 -95
- package/cjs/redis-core.module.js.map +1 -1
- package/cjs/redis.interface.d.ts +5 -5
- package/cjs/redis.module.d.ts +2 -4
- package/cjs/redis.module.js +4 -16
- package/cjs/redis.module.js.map +1 -1
- package/cjs/utils.d.ts +2 -0
- package/cjs/utils.js +8 -0
- package/cjs/utils.js.map +1 -0
- package/esm/redis-client.js +67 -6
- package/esm/redis-client.js.map +1 -1
- package/esm/redis-core.module.js +51 -96
- package/esm/redis-core.module.js.map +1 -1
- package/esm/redis.module.js +4 -16
- package/esm/redis.module.js.map +1 -1
- package/esm/utils.js +4 -0
- package/esm/utils.js.map +1 -0
- package/package.json +1 -1
- package/types/redis-client.d.ts +39 -7
- package/types/redis-core.module.d.ts +2 -5
- package/types/redis.interface.d.ts +5 -5
- package/types/redis.module.d.ts +2 -4
- package/types/utils.d.ts +2 -0
- package/cjs/redis-lock.d.ts +0 -39
- package/cjs/redis-lock.js +0 -68
- package/cjs/redis-lock.js.map +0 -1
- package/esm/redis-lock.js +0 -64
- package/esm/redis-lock.js.map +0 -1
- package/types/redis-lock.d.ts +0 -39
package/cjs/redis-client.d.ts
CHANGED
|
@@ -1,10 +1,42 @@
|
|
|
1
1
|
import Redis, { Cluster } from 'ioredis';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
export interface LockOptions {
|
|
3
|
+
expire?: number;
|
|
4
|
+
retryInterval?: number;
|
|
5
|
+
maxRetries?: number;
|
|
4
6
|
}
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export declare class RedisClient {
|
|
8
|
+
readonly isCluster: boolean;
|
|
9
|
+
cluster?: Cluster;
|
|
10
|
+
standalone?: Redis;
|
|
11
|
+
constructor(args: Pick<RedisClient, 'isCluster' | 'cluster' | 'standalone'>);
|
|
12
|
+
get redis(): Redis | Cluster;
|
|
13
|
+
lockPrefix?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Try to lock once
|
|
16
|
+
* @param {string} name redis-lock name
|
|
17
|
+
* @param {number} [expire] milliseconds, TTL for the redis key
|
|
18
|
+
* @returns {boolean} true: success, false: failed
|
|
19
|
+
*/
|
|
20
|
+
tryLock(name: any, expire: any): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* lock, automatically retrying if failed
|
|
23
|
+
* @param {string} name redis-lock name
|
|
24
|
+
* @param {object} [options] Options
|
|
25
|
+
* @param {number} [options.expire=60000] TTL
|
|
26
|
+
* @param {number} [options.retryInterval=100] milliseconds, the interval to retry if failed
|
|
27
|
+
* @param {number} [options.maxRetries=10] max times to retry
|
|
28
|
+
*/
|
|
29
|
+
lock(name: string, options?: LockOptions): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Unlock a redis-lock by name
|
|
32
|
+
* @param {string} name redis-lock name
|
|
33
|
+
*/
|
|
34
|
+
unlock(name: any): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Set TTL for a redis-lock
|
|
37
|
+
* @param {string} name redis-lock name
|
|
38
|
+
* @param {number} milliseconds TTL
|
|
39
|
+
*/
|
|
40
|
+
setLockTTL(name: any, milliseconds: any): Promise<boolean>;
|
|
41
|
+
private _getLockKey;
|
|
10
42
|
}
|
package/cjs/redis-client.js
CHANGED
|
@@ -1,15 +1,74 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
exports.RedisClient = void 0;
|
|
4
|
+
const putil_varhelpers_1 = require("putil-varhelpers");
|
|
5
|
+
class RedisClient {
|
|
6
|
+
constructor(args) {
|
|
7
|
+
Object.assign(this, args);
|
|
8
|
+
}
|
|
9
|
+
get redis() {
|
|
10
|
+
return (this.cluster || this.standalone);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Try to lock once
|
|
14
|
+
* @param {string} name redis-lock name
|
|
15
|
+
* @param {number} [expire] milliseconds, TTL for the redis key
|
|
16
|
+
* @returns {boolean} true: success, false: failed
|
|
17
|
+
*/
|
|
18
|
+
async tryLock(name, expire) {
|
|
19
|
+
const result = await this.redis.set(this._getLockKey(name), '_lock_', 'PX', expire, 'NX');
|
|
20
|
+
return result !== null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* lock, automatically retrying if failed
|
|
24
|
+
* @param {string} name redis-lock name
|
|
25
|
+
* @param {object} [options] Options
|
|
26
|
+
* @param {number} [options.expire=60000] TTL
|
|
27
|
+
* @param {number} [options.retryInterval=100] milliseconds, the interval to retry if failed
|
|
28
|
+
* @param {number} [options.maxRetries=10] max times to retry
|
|
29
|
+
*/
|
|
30
|
+
async lock(name, options) {
|
|
31
|
+
const expire = (0, putil_varhelpers_1.toNumberDef)(options?.expire, 60000);
|
|
32
|
+
const retryInterval = (0, putil_varhelpers_1.toNumberDef)(options?.retryInterval, 100);
|
|
33
|
+
const maxRetries = (0, putil_varhelpers_1.toNumberDef)(options?.maxRetries, 10);
|
|
34
|
+
let retryTimes = 0;
|
|
35
|
+
// eslint-disable-next-line no-constant-condition
|
|
36
|
+
while (1) {
|
|
37
|
+
if (await this.tryLock(name, expire)) {
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
await sleepAsync(retryInterval);
|
|
42
|
+
if (retryTimes >= maxRetries) {
|
|
43
|
+
throw new Error(`Redis lock "${name}" timed out`);
|
|
44
|
+
}
|
|
45
|
+
retryTimes++;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Unlock a redis-lock by name
|
|
51
|
+
* @param {string} name redis-lock name
|
|
52
|
+
*/
|
|
53
|
+
async unlock(name) {
|
|
54
|
+
const s = 'if redis.call(\'get\', KEYS[1]) == ARGV[1] then return redis.call(\'del\', KEYS[1]) else return 0 end';
|
|
55
|
+
await this.redis.eval(s, 1, this._getLockKey(name), '_lock_');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Set TTL for a redis-lock
|
|
59
|
+
* @param {string} name redis-lock name
|
|
60
|
+
* @param {number} milliseconds TTL
|
|
61
|
+
*/
|
|
62
|
+
async setLockTTL(name, milliseconds) {
|
|
63
|
+
const result = await this.redis.pexpire(this._getLockKey(name), milliseconds);
|
|
64
|
+
return !!result;
|
|
65
|
+
}
|
|
66
|
+
_getLockKey(name) {
|
|
67
|
+
return (this.lockPrefix || 'lock:') + name;
|
|
68
|
+
}
|
|
8
69
|
}
|
|
9
70
|
exports.RedisClient = RedisClient;
|
|
10
|
-
|
|
71
|
+
async function sleepAsync(ms) {
|
|
72
|
+
return new Promise(resolve => setTimeout(resolve, Number(ms)));
|
|
11
73
|
}
|
|
12
|
-
exports.RedisCluster = RedisCluster;
|
|
13
|
-
Object.assign(RedisClient.prototype, redis_lock_js_1.RedisLock.prototype);
|
|
14
|
-
Object.assign(RedisCluster.prototype, redis_lock_js_1.RedisLock.prototype);
|
|
15
74
|
//# sourceMappingURL=redis-client.js.map
|
package/cjs/redis-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-client.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"redis-client.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis-client.ts"],"names":[],"mappings":";;;AACA,uDAA+C;AAQ/C,MAAa,WAAW;IAKtB,YAAY,IAA+D;QACzE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,UAAU,CAAsB,CAAC;IAChE,CAAC;IAID;;;;;OAKG;IACI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1F,OAAO,MAAM,KAAK,IAAI,CAAC;IACzB,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,OAAqB;QACnD,MAAM,MAAM,GAAG,IAAA,8BAAW,EAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACnD,MAAM,aAAa,GAAG,IAAA,8BAAW,EAAC,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,IAAA,8BAAW,EAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAExD,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,iDAAiD;QACjD,OAAO,CAAC,EAAE;YACR,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;gBACpC,MAAM;aACP;iBAAM;gBACL,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;gBAChC,IAAI,UAAU,IAAI,UAAU,EAAE;oBAC5B,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,aAAa,CAAC,CAAC;iBACnD;gBACD,UAAU,EAAE,CAAC;aACd;SACF;IACH,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,MAAM,CAAC,IAAI;QACtB,MAAM,CAAC,GAAG,uGAAuG,CAAC;QAClH,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;IAChE,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,YAAY;QACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CACnC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EACtB,YAAY,CACf,CAAC;QACF,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAEO,WAAW,CAAC,IAAI;QACtB,OAAO,CAAC,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7C,CAAC;CAEF;AAhFD,kCAgFC;AAED,KAAK,UAAU,UAAU,CAAC,EAAU;IAClC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -5,11 +5,8 @@ export declare class RedisCoreModule implements OnApplicationShutdown {
|
|
|
5
5
|
private readonly options;
|
|
6
6
|
private readonly moduleRef;
|
|
7
7
|
constructor(options: RedisClientOptions | RedisClusterOptions, moduleRef: ModuleRef);
|
|
8
|
-
static
|
|
9
|
-
static
|
|
10
|
-
static registerCluster(options: RedisClusterOptions): DynamicModule;
|
|
11
|
-
static registerClusterAsync(asyncOptions: RedisClusterAsyncOptions): DynamicModule;
|
|
8
|
+
static forRoot(options: RedisClientOptions | RedisClusterOptions): DynamicModule;
|
|
9
|
+
static forRootAsync(asyncOptions: RedisClientAsyncOptions | RedisClusterAsyncOptions): DynamicModule;
|
|
12
10
|
private static _createClient;
|
|
13
|
-
private static _createCluster;
|
|
14
11
|
onApplicationShutdown(): Promise<void>;
|
|
15
12
|
}
|
package/cjs/redis-core.module.js
CHANGED
|
@@ -4,22 +4,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.RedisCoreModule = void 0;
|
|
5
5
|
const tslib_1 = require("tslib");
|
|
6
6
|
const crypto = tslib_1.__importStar(require("crypto"));
|
|
7
|
+
const ioredis_1 = tslib_1.__importStar(require("ioredis"));
|
|
7
8
|
const common_1 = require("@nestjs/common");
|
|
8
9
|
const core_1 = require("@nestjs/core");
|
|
9
10
|
const redis_constants_js_1 = require("./redis.constants.js");
|
|
10
11
|
const redis_client_js_1 = require("./redis-client.js");
|
|
12
|
+
const utils_js_1 = require("./utils.js");
|
|
11
13
|
let RedisCoreModule = exports.RedisCoreModule = RedisCoreModule_1 = class RedisCoreModule {
|
|
12
14
|
constructor(options, moduleRef) {
|
|
13
15
|
this.options = options;
|
|
14
16
|
this.moduleRef = moduleRef;
|
|
15
17
|
}
|
|
16
|
-
static
|
|
18
|
+
static forRoot(options) {
|
|
17
19
|
const optionsProvider = {
|
|
18
20
|
provide: redis_constants_js_1.IOREDIS_MODULE_OPTIONS,
|
|
19
21
|
useValue: options
|
|
20
22
|
};
|
|
23
|
+
const token = options.token || redis_client_js_1.RedisClient;
|
|
21
24
|
const connectionProvider = {
|
|
22
|
-
provide:
|
|
25
|
+
provide: token,
|
|
23
26
|
useFactory: () => this._createClient(options)
|
|
24
27
|
};
|
|
25
28
|
return {
|
|
@@ -28,11 +31,12 @@ let RedisCoreModule = exports.RedisCoreModule = RedisCoreModule_1 = class RedisC
|
|
|
28
31
|
exports: [connectionProvider]
|
|
29
32
|
};
|
|
30
33
|
}
|
|
31
|
-
static
|
|
34
|
+
static forRootAsync(asyncOptions) {
|
|
32
35
|
if (!asyncOptions.useFactory)
|
|
33
36
|
throw new Error('Invalid configuration. Must provide "useFactory"');
|
|
37
|
+
const token = asyncOptions.token || redis_client_js_1.RedisClient;
|
|
34
38
|
const connectionProvider = {
|
|
35
|
-
provide:
|
|
39
|
+
provide: token,
|
|
36
40
|
inject: [redis_constants_js_1.IOREDIS_MODULE_OPTIONS],
|
|
37
41
|
useFactory: async (moduleOptions) => {
|
|
38
42
|
return this._createClient(moduleOptions);
|
|
@@ -56,113 +60,64 @@ let RedisCoreModule = exports.RedisCoreModule = RedisCoreModule_1 = class RedisC
|
|
|
56
60
|
exports: [connectionProvider]
|
|
57
61
|
};
|
|
58
62
|
}
|
|
59
|
-
static registerCluster(options) {
|
|
60
|
-
const optionsProvider = {
|
|
61
|
-
provide: redis_constants_js_1.IOREDIS_MODULE_OPTIONS,
|
|
62
|
-
useValue: options
|
|
63
|
-
};
|
|
64
|
-
const connectionProvider = {
|
|
65
|
-
provide: options.token || redis_client_js_1.RedisCluster,
|
|
66
|
-
useFactory: () => this._createCluster(options)
|
|
67
|
-
};
|
|
68
|
-
return {
|
|
69
|
-
module: RedisCoreModule_1,
|
|
70
|
-
providers: [connectionProvider, optionsProvider],
|
|
71
|
-
exports: [connectionProvider]
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
static registerClusterAsync(asyncOptions) {
|
|
75
|
-
if (!asyncOptions.useFactory)
|
|
76
|
-
throw new Error('Invalid configuration. Must provide "useFactory"');
|
|
77
|
-
const connectionProvider = {
|
|
78
|
-
provide: asyncOptions.token || redis_client_js_1.RedisCluster,
|
|
79
|
-
inject: [redis_constants_js_1.IOREDIS_MODULE_OPTIONS],
|
|
80
|
-
useFactory: async (moduleOptions) => {
|
|
81
|
-
return this._createCluster(moduleOptions);
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
return {
|
|
85
|
-
module: RedisCoreModule_1,
|
|
86
|
-
imports: asyncOptions.imports,
|
|
87
|
-
providers: [
|
|
88
|
-
{
|
|
89
|
-
provide: redis_constants_js_1.IOREDIS_MODULE_OPTIONS,
|
|
90
|
-
useFactory: asyncOptions.useFactory,
|
|
91
|
-
inject: asyncOptions.inject || []
|
|
92
|
-
},
|
|
93
|
-
connectionProvider,
|
|
94
|
-
{
|
|
95
|
-
provide: redis_constants_js_1.IOREDIS_MODULE_TOKEN,
|
|
96
|
-
useValue: crypto.randomUUID()
|
|
97
|
-
}
|
|
98
|
-
],
|
|
99
|
-
exports: [connectionProvider]
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
63
|
static async _createClient(options) {
|
|
103
|
-
if (options.host && options.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
options
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
64
|
+
if (options.host && options.nodes)
|
|
65
|
+
throw new TypeError(`You should set either "host" or "nodes", not both`);
|
|
66
|
+
const isCluster = (0, utils_js_1.isClusterOptions)(options);
|
|
67
|
+
let client;
|
|
68
|
+
if (isCluster) {
|
|
69
|
+
const clusterOptions = {
|
|
70
|
+
...options
|
|
71
|
+
};
|
|
72
|
+
delete clusterOptions.name;
|
|
73
|
+
delete clusterOptions.nodes;
|
|
74
|
+
const cluster = new ioredis_1.Cluster(options.nodes, clusterOptions);
|
|
75
|
+
client = new redis_client_js_1.RedisClient({
|
|
76
|
+
isCluster,
|
|
77
|
+
cluster
|
|
78
|
+
});
|
|
118
79
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
80
|
+
else {
|
|
81
|
+
if (options.host && options.host.includes('://')) {
|
|
82
|
+
const url = new URL(options.host);
|
|
83
|
+
options.host = url.hostname;
|
|
84
|
+
if (url.port)
|
|
85
|
+
options.port = parseInt(url.port, 10);
|
|
86
|
+
if (url.username)
|
|
87
|
+
options.username = url.username;
|
|
88
|
+
if (url.password)
|
|
89
|
+
options.password = url.password;
|
|
90
|
+
if (url.protocol === 'rediss:') { // @ts-ignore
|
|
91
|
+
options.tls = true;
|
|
92
|
+
}
|
|
93
|
+
const db = parseInt(url.pathname.substring(1), 10);
|
|
94
|
+
if (db > 0)
|
|
95
|
+
options.db = db;
|
|
96
|
+
}
|
|
97
|
+
const standalone = new ioredis_1.default(options);
|
|
98
|
+
client = new redis_client_js_1.RedisClient({
|
|
99
|
+
isCluster,
|
|
100
|
+
standalone
|
|
130
101
|
});
|
|
131
102
|
}
|
|
132
|
-
return client;
|
|
133
|
-
}
|
|
134
|
-
static async _createCluster(options) {
|
|
135
|
-
const clusterOptions = {
|
|
136
|
-
...options
|
|
137
|
-
};
|
|
138
|
-
delete clusterOptions.name;
|
|
139
|
-
delete clusterOptions.nodes;
|
|
140
|
-
const cluster = new redis_client_js_1.RedisCluster(options.nodes, clusterOptions);
|
|
141
103
|
if (!options.lazyConnect) {
|
|
142
104
|
await new Promise((resolve, reject) => {
|
|
143
|
-
|
|
144
|
-
|
|
105
|
+
client.redis.once('ready', () => {
|
|
106
|
+
client.redis.removeListener('error', reject);
|
|
145
107
|
resolve();
|
|
146
108
|
});
|
|
147
|
-
|
|
148
|
-
|
|
109
|
+
client.redis.once('error', (e) => {
|
|
110
|
+
client.redis.removeListener('ready', resolve);
|
|
149
111
|
reject(e);
|
|
150
112
|
});
|
|
151
113
|
});
|
|
152
114
|
}
|
|
153
|
-
return
|
|
115
|
+
return client;
|
|
154
116
|
}
|
|
155
117
|
async onApplicationShutdown() {
|
|
156
118
|
try {
|
|
157
119
|
const client = this.moduleRef.get(this.options.token || redis_client_js_1.RedisClient);
|
|
158
|
-
await client.quit();
|
|
159
|
-
}
|
|
160
|
-
catch {
|
|
161
|
-
//
|
|
162
|
-
}
|
|
163
|
-
try {
|
|
164
|
-
const cluster = this.moduleRef.get(this.options.token || redis_client_js_1.RedisCluster);
|
|
165
|
-
await cluster.quit();
|
|
120
|
+
await client.redis.quit();
|
|
166
121
|
}
|
|
167
122
|
catch {
|
|
168
123
|
//
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-core.module.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis-core.module.ts"],"names":[],"mappings":";;;;;AAAA,uDAAiC;
|
|
1
|
+
{"version":3,"file":"redis-core.module.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis-core.module.ts"],"names":[],"mappings":"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"}
|
package/cjs/redis.interface.d.ts
CHANGED
|
@@ -8,20 +8,20 @@ export interface RedisClientOptions extends RedisOptions {
|
|
|
8
8
|
*/
|
|
9
9
|
token?: any;
|
|
10
10
|
}
|
|
11
|
-
export interface
|
|
11
|
+
export interface RedisClusterOptions extends ClusterOptions {
|
|
12
12
|
/**
|
|
13
13
|
* Injection token
|
|
14
14
|
*/
|
|
15
15
|
token?: any;
|
|
16
|
-
|
|
17
|
-
inject?: any[];
|
|
16
|
+
nodes: ClusterNode[];
|
|
18
17
|
}
|
|
19
|
-
export interface
|
|
18
|
+
export interface RedisClientAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
20
19
|
/**
|
|
21
20
|
* Injection token
|
|
22
21
|
*/
|
|
23
22
|
token?: any;
|
|
24
|
-
|
|
23
|
+
useFactory?: (...args: any[]) => Promise<RedisClientOptions> | RedisClientOptions;
|
|
24
|
+
inject?: any[];
|
|
25
25
|
}
|
|
26
26
|
export interface RedisClusterAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
27
27
|
/**
|
package/cjs/redis.module.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { RedisClientAsyncOptions, RedisClientOptions, RedisClusterAsyncOptions, RedisClusterOptions } from './redis.interface.js';
|
|
3
3
|
export declare class RedisModule {
|
|
4
|
-
static
|
|
5
|
-
static
|
|
6
|
-
static registerCluster(options: RedisClusterOptions): DynamicModule;
|
|
7
|
-
static registerClusterAsync(options: RedisClusterAsyncOptions): DynamicModule;
|
|
4
|
+
static forRoot(options: RedisClientOptions | RedisClusterOptions): DynamicModule;
|
|
5
|
+
static forRootAsync(options: RedisClientAsyncOptions | RedisClusterAsyncOptions): DynamicModule;
|
|
8
6
|
}
|
package/cjs/redis.module.js
CHANGED
|
@@ -6,28 +6,16 @@ const tslib_1 = require("tslib");
|
|
|
6
6
|
const common_1 = require("@nestjs/common");
|
|
7
7
|
const redis_core_module_js_1 = require("./redis-core.module.js");
|
|
8
8
|
let RedisModule = exports.RedisModule = RedisModule_1 = class RedisModule {
|
|
9
|
-
static
|
|
9
|
+
static forRoot(options) {
|
|
10
10
|
return {
|
|
11
11
|
module: RedisModule_1,
|
|
12
|
-
imports: [redis_core_module_js_1.RedisCoreModule.
|
|
12
|
+
imports: [redis_core_module_js_1.RedisCoreModule.forRoot(options)]
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
-
static
|
|
15
|
+
static forRootAsync(options) {
|
|
16
16
|
return {
|
|
17
17
|
module: RedisModule_1,
|
|
18
|
-
imports: [redis_core_module_js_1.RedisCoreModule.
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
static registerCluster(options) {
|
|
22
|
-
return {
|
|
23
|
-
module: RedisModule_1,
|
|
24
|
-
imports: [redis_core_module_js_1.RedisCoreModule.registerCluster(options)]
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
static registerClusterAsync(options) {
|
|
28
|
-
return {
|
|
29
|
-
module: RedisModule_1,
|
|
30
|
-
imports: [redis_core_module_js_1.RedisCoreModule.registerClusterAsync(options)]
|
|
18
|
+
imports: [redis_core_module_js_1.RedisCoreModule.forRootAsync(options)]
|
|
31
19
|
};
|
|
32
20
|
}
|
|
33
21
|
};
|
package/cjs/redis.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.module.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAAuD;AAOvD,iEAAyD;AAGlD,IAAM,WAAW,yCAAjB,MAAM,WAAW;IACtB,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"redis.module.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAAuD;AAOvD,iEAAyD;AAGlD,IAAM,WAAW,yCAAjB,MAAM,WAAW;IACtB,MAAM,CAAC,OAAO,CAAC,OAAiD;QAC9D,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,OAAO,EAAE,CAAC,sCAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SAC5C,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAA2D;QAC7E,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,OAAO,EAAE,CAAC,sCAAe,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;SACjD,CAAC;IACJ,CAAC;CAEF,CAAA;sBAfY,WAAW;IADvB,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,WAAW,CAevB"}
|
package/cjs/utils.d.ts
ADDED
package/cjs/utils.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isClusterOptions = void 0;
|
|
4
|
+
function isClusterOptions(options) {
|
|
5
|
+
return options && typeof options === 'object' && Array.isArray(options.nodes);
|
|
6
|
+
}
|
|
7
|
+
exports.isClusterOptions = isClusterOptions;
|
|
8
|
+
//# sourceMappingURL=utils.js.map
|
package/cjs/utils.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../packages/ioredis/src/utils.ts"],"names":[],"mappings":";;;AAEA,SAAgB,gBAAgB,CAAC,OAAO;IACtC,OAAO,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAChF,CAAC;AAFD,4CAEC"}
|
package/esm/redis-client.js
CHANGED
|
@@ -1,9 +1,70 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { toNumberDef } from 'putil-varhelpers';
|
|
2
|
+
export class RedisClient {
|
|
3
|
+
constructor(args) {
|
|
4
|
+
Object.assign(this, args);
|
|
5
|
+
}
|
|
6
|
+
get redis() {
|
|
7
|
+
return (this.cluster || this.standalone);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Try to lock once
|
|
11
|
+
* @param {string} name redis-lock name
|
|
12
|
+
* @param {number} [expire] milliseconds, TTL for the redis key
|
|
13
|
+
* @returns {boolean} true: success, false: failed
|
|
14
|
+
*/
|
|
15
|
+
async tryLock(name, expire) {
|
|
16
|
+
const result = await this.redis.set(this._getLockKey(name), '_lock_', 'PX', expire, 'NX');
|
|
17
|
+
return result !== null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* lock, automatically retrying if failed
|
|
21
|
+
* @param {string} name redis-lock name
|
|
22
|
+
* @param {object} [options] Options
|
|
23
|
+
* @param {number} [options.expire=60000] TTL
|
|
24
|
+
* @param {number} [options.retryInterval=100] milliseconds, the interval to retry if failed
|
|
25
|
+
* @param {number} [options.maxRetries=10] max times to retry
|
|
26
|
+
*/
|
|
27
|
+
async lock(name, options) {
|
|
28
|
+
const expire = toNumberDef(options?.expire, 60000);
|
|
29
|
+
const retryInterval = toNumberDef(options?.retryInterval, 100);
|
|
30
|
+
const maxRetries = toNumberDef(options?.maxRetries, 10);
|
|
31
|
+
let retryTimes = 0;
|
|
32
|
+
// eslint-disable-next-line no-constant-condition
|
|
33
|
+
while (1) {
|
|
34
|
+
if (await this.tryLock(name, expire)) {
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
await sleepAsync(retryInterval);
|
|
39
|
+
if (retryTimes >= maxRetries) {
|
|
40
|
+
throw new Error(`Redis lock "${name}" timed out`);
|
|
41
|
+
}
|
|
42
|
+
retryTimes++;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Unlock a redis-lock by name
|
|
48
|
+
* @param {string} name redis-lock name
|
|
49
|
+
*/
|
|
50
|
+
async unlock(name) {
|
|
51
|
+
const s = 'if redis.call(\'get\', KEYS[1]) == ARGV[1] then return redis.call(\'del\', KEYS[1]) else return 0 end';
|
|
52
|
+
await this.redis.eval(s, 1, this._getLockKey(name), '_lock_');
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Set TTL for a redis-lock
|
|
56
|
+
* @param {string} name redis-lock name
|
|
57
|
+
* @param {number} milliseconds TTL
|
|
58
|
+
*/
|
|
59
|
+
async setLockTTL(name, milliseconds) {
|
|
60
|
+
const result = await this.redis.pexpire(this._getLockKey(name), milliseconds);
|
|
61
|
+
return !!result;
|
|
62
|
+
}
|
|
63
|
+
_getLockKey(name) {
|
|
64
|
+
return (this.lockPrefix || 'lock:') + name;
|
|
65
|
+
}
|
|
4
66
|
}
|
|
5
|
-
|
|
67
|
+
async function sleepAsync(ms) {
|
|
68
|
+
return new Promise(resolve => setTimeout(resolve, Number(ms)));
|
|
6
69
|
}
|
|
7
|
-
Object.assign(RedisClient.prototype, RedisLock.prototype);
|
|
8
|
-
Object.assign(RedisCluster.prototype, RedisLock.prototype);
|
|
9
70
|
//# sourceMappingURL=redis-client.js.map
|
package/esm/redis-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-client.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"redis-client.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQ/C,MAAM,OAAO,WAAW;IAKtB,YAAY,IAA+D;QACzE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,UAAU,CAAsB,CAAC;IAChE,CAAC;IAID;;;;;OAKG;IACI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1F,OAAO,MAAM,KAAK,IAAI,CAAC;IACzB,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,OAAqB;QACnD,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACnD,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAExD,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,iDAAiD;QACjD,OAAO,CAAC,EAAE;YACR,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;gBACpC,MAAM;aACP;iBAAM;gBACL,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;gBAChC,IAAI,UAAU,IAAI,UAAU,EAAE;oBAC5B,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,aAAa,CAAC,CAAC;iBACnD;gBACD,UAAU,EAAE,CAAC;aACd;SACF;IACH,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,MAAM,CAAC,IAAI;QACtB,MAAM,CAAC,GAAG,uGAAuG,CAAC;QAClH,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;IAChE,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,YAAY;QACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CACnC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EACtB,YAAY,CACf,CAAC;QACF,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAEO,WAAW,CAAC,IAAI;QACtB,OAAO,CAAC,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7C,CAAC;CAEF;AAED,KAAK,UAAU,UAAU,CAAC,EAAU;IAClC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
|
package/esm/redis-core.module.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
var RedisCoreModule_1;
|
|
2
2
|
import { __decorate, __metadata, __param } from "tslib";
|
|
3
3
|
import * as crypto from 'crypto';
|
|
4
|
+
import Redis, { Cluster } from 'ioredis';
|
|
4
5
|
import { Global, Inject, Module, } from '@nestjs/common';
|
|
5
6
|
import { ModuleRef } from '@nestjs/core';
|
|
6
7
|
import { IOREDIS_MODULE_OPTIONS, IOREDIS_MODULE_TOKEN } from './redis.constants.js';
|
|
7
|
-
import { RedisClient
|
|
8
|
+
import { RedisClient } from './redis-client.js';
|
|
9
|
+
import { isClusterOptions } from './utils.js';
|
|
8
10
|
export let RedisCoreModule = RedisCoreModule_1 = class RedisCoreModule {
|
|
9
11
|
constructor(options, moduleRef) {
|
|
10
12
|
this.options = options;
|
|
11
13
|
this.moduleRef = moduleRef;
|
|
12
14
|
}
|
|
13
|
-
static
|
|
15
|
+
static forRoot(options) {
|
|
14
16
|
const optionsProvider = {
|
|
15
17
|
provide: IOREDIS_MODULE_OPTIONS,
|
|
16
18
|
useValue: options
|
|
17
19
|
};
|
|
20
|
+
const token = options.token || RedisClient;
|
|
18
21
|
const connectionProvider = {
|
|
19
|
-
provide:
|
|
22
|
+
provide: token,
|
|
20
23
|
useFactory: () => this._createClient(options)
|
|
21
24
|
};
|
|
22
25
|
return {
|
|
@@ -25,11 +28,12 @@ export let RedisCoreModule = RedisCoreModule_1 = class RedisCoreModule {
|
|
|
25
28
|
exports: [connectionProvider]
|
|
26
29
|
};
|
|
27
30
|
}
|
|
28
|
-
static
|
|
31
|
+
static forRootAsync(asyncOptions) {
|
|
29
32
|
if (!asyncOptions.useFactory)
|
|
30
33
|
throw new Error('Invalid configuration. Must provide "useFactory"');
|
|
34
|
+
const token = asyncOptions.token || RedisClient;
|
|
31
35
|
const connectionProvider = {
|
|
32
|
-
provide:
|
|
36
|
+
provide: token,
|
|
33
37
|
inject: [IOREDIS_MODULE_OPTIONS],
|
|
34
38
|
useFactory: async (moduleOptions) => {
|
|
35
39
|
return this._createClient(moduleOptions);
|
|
@@ -53,113 +57,64 @@ export let RedisCoreModule = RedisCoreModule_1 = class RedisCoreModule {
|
|
|
53
57
|
exports: [connectionProvider]
|
|
54
58
|
};
|
|
55
59
|
}
|
|
56
|
-
static registerCluster(options) {
|
|
57
|
-
const optionsProvider = {
|
|
58
|
-
provide: IOREDIS_MODULE_OPTIONS,
|
|
59
|
-
useValue: options
|
|
60
|
-
};
|
|
61
|
-
const connectionProvider = {
|
|
62
|
-
provide: options.token || RedisCluster,
|
|
63
|
-
useFactory: () => this._createCluster(options)
|
|
64
|
-
};
|
|
65
|
-
return {
|
|
66
|
-
module: RedisCoreModule_1,
|
|
67
|
-
providers: [connectionProvider, optionsProvider],
|
|
68
|
-
exports: [connectionProvider]
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
static registerClusterAsync(asyncOptions) {
|
|
72
|
-
if (!asyncOptions.useFactory)
|
|
73
|
-
throw new Error('Invalid configuration. Must provide "useFactory"');
|
|
74
|
-
const connectionProvider = {
|
|
75
|
-
provide: asyncOptions.token || RedisCluster,
|
|
76
|
-
inject: [IOREDIS_MODULE_OPTIONS],
|
|
77
|
-
useFactory: async (moduleOptions) => {
|
|
78
|
-
return this._createCluster(moduleOptions);
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
return {
|
|
82
|
-
module: RedisCoreModule_1,
|
|
83
|
-
imports: asyncOptions.imports,
|
|
84
|
-
providers: [
|
|
85
|
-
{
|
|
86
|
-
provide: IOREDIS_MODULE_OPTIONS,
|
|
87
|
-
useFactory: asyncOptions.useFactory,
|
|
88
|
-
inject: asyncOptions.inject || []
|
|
89
|
-
},
|
|
90
|
-
connectionProvider,
|
|
91
|
-
{
|
|
92
|
-
provide: IOREDIS_MODULE_TOKEN,
|
|
93
|
-
useValue: crypto.randomUUID()
|
|
94
|
-
}
|
|
95
|
-
],
|
|
96
|
-
exports: [connectionProvider]
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
60
|
static async _createClient(options) {
|
|
100
|
-
if (options.host && options.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
options
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
61
|
+
if (options.host && options.nodes)
|
|
62
|
+
throw new TypeError(`You should set either "host" or "nodes", not both`);
|
|
63
|
+
const isCluster = isClusterOptions(options);
|
|
64
|
+
let client;
|
|
65
|
+
if (isCluster) {
|
|
66
|
+
const clusterOptions = {
|
|
67
|
+
...options
|
|
68
|
+
};
|
|
69
|
+
delete clusterOptions.name;
|
|
70
|
+
delete clusterOptions.nodes;
|
|
71
|
+
const cluster = new Cluster(options.nodes, clusterOptions);
|
|
72
|
+
client = new RedisClient({
|
|
73
|
+
isCluster,
|
|
74
|
+
cluster
|
|
75
|
+
});
|
|
115
76
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
77
|
+
else {
|
|
78
|
+
if (options.host && options.host.includes('://')) {
|
|
79
|
+
const url = new URL(options.host);
|
|
80
|
+
options.host = url.hostname;
|
|
81
|
+
if (url.port)
|
|
82
|
+
options.port = parseInt(url.port, 10);
|
|
83
|
+
if (url.username)
|
|
84
|
+
options.username = url.username;
|
|
85
|
+
if (url.password)
|
|
86
|
+
options.password = url.password;
|
|
87
|
+
if (url.protocol === 'rediss:') { // @ts-ignore
|
|
88
|
+
options.tls = true;
|
|
89
|
+
}
|
|
90
|
+
const db = parseInt(url.pathname.substring(1), 10);
|
|
91
|
+
if (db > 0)
|
|
92
|
+
options.db = db;
|
|
93
|
+
}
|
|
94
|
+
const standalone = new Redis(options);
|
|
95
|
+
client = new RedisClient({
|
|
96
|
+
isCluster,
|
|
97
|
+
standalone
|
|
127
98
|
});
|
|
128
99
|
}
|
|
129
|
-
return client;
|
|
130
|
-
}
|
|
131
|
-
static async _createCluster(options) {
|
|
132
|
-
const clusterOptions = {
|
|
133
|
-
...options
|
|
134
|
-
};
|
|
135
|
-
delete clusterOptions.name;
|
|
136
|
-
delete clusterOptions.nodes;
|
|
137
|
-
const cluster = new RedisCluster(options.nodes, clusterOptions);
|
|
138
100
|
if (!options.lazyConnect) {
|
|
139
101
|
await new Promise((resolve, reject) => {
|
|
140
|
-
|
|
141
|
-
|
|
102
|
+
client.redis.once('ready', () => {
|
|
103
|
+
client.redis.removeListener('error', reject);
|
|
142
104
|
resolve();
|
|
143
105
|
});
|
|
144
|
-
|
|
145
|
-
|
|
106
|
+
client.redis.once('error', (e) => {
|
|
107
|
+
client.redis.removeListener('ready', resolve);
|
|
146
108
|
reject(e);
|
|
147
109
|
});
|
|
148
110
|
});
|
|
149
111
|
}
|
|
150
|
-
return
|
|
112
|
+
return client;
|
|
151
113
|
}
|
|
152
114
|
async onApplicationShutdown() {
|
|
153
115
|
try {
|
|
154
116
|
const client = this.moduleRef.get(this.options.token || RedisClient);
|
|
155
|
-
await client.quit();
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
//
|
|
159
|
-
}
|
|
160
|
-
try {
|
|
161
|
-
const cluster = this.moduleRef.get(this.options.token || RedisCluster);
|
|
162
|
-
await cluster.quit();
|
|
117
|
+
await client.redis.quit();
|
|
163
118
|
}
|
|
164
119
|
catch {
|
|
165
120
|
//
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-core.module.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis-core.module.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"redis-core.module.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis-core.module.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EACU,MAAM,EAAE,MAAM,EAAE,MAAM,GAEtC,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAIvC,WAAM,eAAe,uBAArB,MAAM,eAAe;IAE1B,YAEqB,OAAiD,EACjD,SAAoB;QADpB,YAAO,GAAP,OAAO,CAA0C;QACjD,cAAS,GAAT,SAAS,CAAW;IAEzC,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,OAAiD;QAC9D,MAAM,eAAe,GAAG;YACtB,OAAO,EAAE,sBAAsB;YAC/B,QAAQ,EAAE,OAAO;SAClB,CAAC;QACF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC;QAC3C,MAAM,kBAAkB,GAAG;YACzB,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;SAC9C,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,iBAAe;YACvB,SAAS,EAAE,CAAC,kBAAkB,EAAE,eAAe,CAAC;YAChD,OAAO,EAAE,CAAC,kBAAkB,CAAC;SAC9B,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,YAAgE;QAClF,IAAI,CAAC,YAAY,CAAC,UAAU;YAC1B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAEtE,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,IAAI,WAAW,CAAC;QAEhD,MAAM,kBAAkB,GAAG;YACzB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,CAAC,sBAAsB,CAAC;YAChC,UAAU,EAAE,KAAK,EAAE,aAAiC,EAAE,EAAE;gBACtD,OAAO,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;YAC3C,CAAC;SACF,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,iBAAe;YACvB,OAAO,EAAE,YAAY,CAAC,OAAO;YAC7B,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,sBAAsB;oBAC/B,UAAU,EAAE,YAAY,CAAC,UAAU;oBACnC,MAAM,EAAE,YAAY,CAAC,MAAM,IAAI,EAAE;iBAClC;gBACD;oBACE,OAAO,EAAE,oBAAoB;oBAC7B,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE;iBAC9B;gBACD,kBAAkB;aACnB;YACD,OAAO,EAAE,CAAC,kBAAkB,CAAC;SAC9B,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,OAA2B;QAC5D,IAAI,OAAO,CAAC,IAAI,IAAK,OAAe,CAAC,KAAK;YACxC,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAC;QAC3E,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,MAAmB,CAAC;QACxB,IAAI,SAAS,EAAE;YACb,MAAM,cAAc,GAAmB;gBACrC,GAAG,OAAO;aACX,CAAC;YACF,OAAQ,cAAsB,CAAC,IAAI,CAAC;YACpC,OAAQ,cAAsB,CAAC,KAAK,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;YAC3D,MAAM,GAAG,IAAI,WAAW,CAAC;gBACvB,SAAS;gBACT,OAAO;aACR,CAAC,CAAA;SACH;aAAM;YACL,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;gBAChD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAClC,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC;gBAC5B,IAAI,GAAG,CAAC,IAAI;oBACV,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACxC,IAAI,GAAG,CAAC,QAAQ;oBACd,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;gBAClC,IAAI,GAAG,CAAC,QAAQ;oBACd,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;gBAClC,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,EAAE,aAAa;oBAC7C,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;iBACpB;gBACD,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACnD,IAAI,EAAE,GAAG,CAAC;oBACR,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;aACnB;YACD,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,OAAO,CAAQ,CAAC;YAC7C,MAAM,GAAG,IAAI,WAAW,CAAC;gBACvB,SAAS;gBACT,UAAU;aACX,CAAC,CAAA;SACH;QAED,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;YACxB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;oBAC9B,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;oBAC7C,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;gBACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;oBAC/B,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBAC9C,MAAM,CAAC,CAAC,CAAC,CAAC;gBACZ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;SACJ;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,qBAAqB;QACzB,IAAI;YACF,MAAM,MAAM,GAAgB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC,CAAC;YAClF,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC3B;QAAC,MAAM;YACN,EAAE;SACH;IACH,CAAC;CAEF,CAAA;AA5HY,eAAe;IAF3B,MAAM,EAAE;IACR,MAAM,CAAC,EAAE,CAAC;IAIJ,WAAA,MAAM,CAAC,sBAAsB,CAAC,CAAA;6CAEH,SAAS;GAL9B,eAAe,CA4H3B"}
|
package/esm/redis.module.js
CHANGED
|
@@ -3,28 +3,16 @@ import { __decorate } from "tslib";
|
|
|
3
3
|
import { Module } from '@nestjs/common';
|
|
4
4
|
import { RedisCoreModule } from './redis-core.module.js';
|
|
5
5
|
export let RedisModule = RedisModule_1 = class RedisModule {
|
|
6
|
-
static
|
|
6
|
+
static forRoot(options) {
|
|
7
7
|
return {
|
|
8
8
|
module: RedisModule_1,
|
|
9
|
-
imports: [RedisCoreModule.
|
|
9
|
+
imports: [RedisCoreModule.forRoot(options)]
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
|
-
static
|
|
12
|
+
static forRootAsync(options) {
|
|
13
13
|
return {
|
|
14
14
|
module: RedisModule_1,
|
|
15
|
-
imports: [RedisCoreModule.
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
static registerCluster(options) {
|
|
19
|
-
return {
|
|
20
|
-
module: RedisModule_1,
|
|
21
|
-
imports: [RedisCoreModule.registerCluster(options)]
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
static registerClusterAsync(options) {
|
|
25
|
-
return {
|
|
26
|
-
module: RedisModule_1,
|
|
27
|
-
imports: [RedisCoreModule.registerClusterAsync(options)]
|
|
15
|
+
imports: [RedisCoreModule.forRootAsync(options)]
|
|
28
16
|
};
|
|
29
17
|
}
|
|
30
18
|
};
|
package/esm/redis.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.module.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis.module.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAiB,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAOvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGlD,WAAM,WAAW,mBAAjB,MAAM,WAAW;IACtB,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"redis.module.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis.module.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAiB,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAOvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGlD,WAAM,WAAW,mBAAjB,MAAM,WAAW;IACtB,MAAM,CAAC,OAAO,CAAC,OAAiD;QAC9D,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,OAAO,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SAC5C,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAA2D;QAC7E,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,OAAO,EAAE,CAAC,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;SACjD,CAAC;IACJ,CAAC;CAEF,CAAA;AAfY,WAAW;IADvB,MAAM,CAAC,EAAE,CAAC;GACE,WAAW,CAevB"}
|
package/esm/utils.js
ADDED
package/esm/utils.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../packages/ioredis/src/utils.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAAC,OAAO;IACtC,OAAO,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAChF,CAAC"}
|
package/package.json
CHANGED
package/types/redis-client.d.ts
CHANGED
|
@@ -1,10 +1,42 @@
|
|
|
1
1
|
import Redis, { Cluster } from 'ioredis';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
export interface LockOptions {
|
|
3
|
+
expire?: number;
|
|
4
|
+
retryInterval?: number;
|
|
5
|
+
maxRetries?: number;
|
|
4
6
|
}
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export declare class RedisClient {
|
|
8
|
+
readonly isCluster: boolean;
|
|
9
|
+
cluster?: Cluster;
|
|
10
|
+
standalone?: Redis;
|
|
11
|
+
constructor(args: Pick<RedisClient, 'isCluster' | 'cluster' | 'standalone'>);
|
|
12
|
+
get redis(): Redis | Cluster;
|
|
13
|
+
lockPrefix?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Try to lock once
|
|
16
|
+
* @param {string} name redis-lock name
|
|
17
|
+
* @param {number} [expire] milliseconds, TTL for the redis key
|
|
18
|
+
* @returns {boolean} true: success, false: failed
|
|
19
|
+
*/
|
|
20
|
+
tryLock(name: any, expire: any): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* lock, automatically retrying if failed
|
|
23
|
+
* @param {string} name redis-lock name
|
|
24
|
+
* @param {object} [options] Options
|
|
25
|
+
* @param {number} [options.expire=60000] TTL
|
|
26
|
+
* @param {number} [options.retryInterval=100] milliseconds, the interval to retry if failed
|
|
27
|
+
* @param {number} [options.maxRetries=10] max times to retry
|
|
28
|
+
*/
|
|
29
|
+
lock(name: string, options?: LockOptions): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Unlock a redis-lock by name
|
|
32
|
+
* @param {string} name redis-lock name
|
|
33
|
+
*/
|
|
34
|
+
unlock(name: any): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Set TTL for a redis-lock
|
|
37
|
+
* @param {string} name redis-lock name
|
|
38
|
+
* @param {number} milliseconds TTL
|
|
39
|
+
*/
|
|
40
|
+
setLockTTL(name: any, milliseconds: any): Promise<boolean>;
|
|
41
|
+
private _getLockKey;
|
|
10
42
|
}
|
|
@@ -5,11 +5,8 @@ export declare class RedisCoreModule implements OnApplicationShutdown {
|
|
|
5
5
|
private readonly options;
|
|
6
6
|
private readonly moduleRef;
|
|
7
7
|
constructor(options: RedisClientOptions | RedisClusterOptions, moduleRef: ModuleRef);
|
|
8
|
-
static
|
|
9
|
-
static
|
|
10
|
-
static registerCluster(options: RedisClusterOptions): DynamicModule;
|
|
11
|
-
static registerClusterAsync(asyncOptions: RedisClusterAsyncOptions): DynamicModule;
|
|
8
|
+
static forRoot(options: RedisClientOptions | RedisClusterOptions): DynamicModule;
|
|
9
|
+
static forRootAsync(asyncOptions: RedisClientAsyncOptions | RedisClusterAsyncOptions): DynamicModule;
|
|
12
10
|
private static _createClient;
|
|
13
|
-
private static _createCluster;
|
|
14
11
|
onApplicationShutdown(): Promise<void>;
|
|
15
12
|
}
|
|
@@ -8,20 +8,20 @@ export interface RedisClientOptions extends RedisOptions {
|
|
|
8
8
|
*/
|
|
9
9
|
token?: any;
|
|
10
10
|
}
|
|
11
|
-
export interface
|
|
11
|
+
export interface RedisClusterOptions extends ClusterOptions {
|
|
12
12
|
/**
|
|
13
13
|
* Injection token
|
|
14
14
|
*/
|
|
15
15
|
token?: any;
|
|
16
|
-
|
|
17
|
-
inject?: any[];
|
|
16
|
+
nodes: ClusterNode[];
|
|
18
17
|
}
|
|
19
|
-
export interface
|
|
18
|
+
export interface RedisClientAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
20
19
|
/**
|
|
21
20
|
* Injection token
|
|
22
21
|
*/
|
|
23
22
|
token?: any;
|
|
24
|
-
|
|
23
|
+
useFactory?: (...args: any[]) => Promise<RedisClientOptions> | RedisClientOptions;
|
|
24
|
+
inject?: any[];
|
|
25
25
|
}
|
|
26
26
|
export interface RedisClusterAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
27
27
|
/**
|
package/types/redis.module.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { RedisClientAsyncOptions, RedisClientOptions, RedisClusterAsyncOptions, RedisClusterOptions } from './redis.interface.js';
|
|
3
3
|
export declare class RedisModule {
|
|
4
|
-
static
|
|
5
|
-
static
|
|
6
|
-
static registerCluster(options: RedisClusterOptions): DynamicModule;
|
|
7
|
-
static registerClusterAsync(options: RedisClusterAsyncOptions): DynamicModule;
|
|
4
|
+
static forRoot(options: RedisClientOptions | RedisClusterOptions): DynamicModule;
|
|
5
|
+
static forRootAsync(options: RedisClientAsyncOptions | RedisClusterAsyncOptions): DynamicModule;
|
|
8
6
|
}
|
package/types/utils.d.ts
ADDED
package/cjs/redis-lock.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import Redis, { Cluster } from 'ioredis';
|
|
2
|
-
export interface LockOptions {
|
|
3
|
-
expire?: number;
|
|
4
|
-
retryInterval?: number;
|
|
5
|
-
maxRetries?: number;
|
|
6
|
-
}
|
|
7
|
-
type This = RedisLock & (Redis | Cluster);
|
|
8
|
-
export declare class RedisLock {
|
|
9
|
-
lockPrefix?: string;
|
|
10
|
-
/**
|
|
11
|
-
* Try to lock once
|
|
12
|
-
* @param {string} name redis-lock name
|
|
13
|
-
* @param {number} [expire] milliseconds, TTL for the redis key
|
|
14
|
-
* @returns {boolean} true: success, false: failed
|
|
15
|
-
*/
|
|
16
|
-
tryLock(this: This, name: any, expire: any): Promise<boolean>;
|
|
17
|
-
/**
|
|
18
|
-
* lock, automatically retrying if failed
|
|
19
|
-
* @param {string} name redis-lock name
|
|
20
|
-
* @param {object} [options] Options
|
|
21
|
-
* @param {number} [options.expire=60000] TTL
|
|
22
|
-
* @param {number} [options.retryInterval=100] milliseconds, the interval to retry if failed
|
|
23
|
-
* @param {number} [options.maxRetries=10] max times to retry
|
|
24
|
-
*/
|
|
25
|
-
lock(this: This, name: string, options?: LockOptions): Promise<void>;
|
|
26
|
-
/**
|
|
27
|
-
* Unlock a redis-lock by name
|
|
28
|
-
* @param {string} name redis-lock name
|
|
29
|
-
*/
|
|
30
|
-
unlock(this: This, name: any): Promise<void>;
|
|
31
|
-
/**
|
|
32
|
-
* Set TTL for a redis-lock
|
|
33
|
-
* @param {string} name redis-lock name
|
|
34
|
-
* @param {number} milliseconds TTL
|
|
35
|
-
*/
|
|
36
|
-
setLockTTL(this: This, name: any, milliseconds: any): Promise<boolean>;
|
|
37
|
-
private _getLockKey;
|
|
38
|
-
}
|
|
39
|
-
export {};
|
package/cjs/redis-lock.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RedisLock = void 0;
|
|
4
|
-
const putil_varhelpers_1 = require("putil-varhelpers");
|
|
5
|
-
class RedisLock {
|
|
6
|
-
/**
|
|
7
|
-
* Try to lock once
|
|
8
|
-
* @param {string} name redis-lock name
|
|
9
|
-
* @param {number} [expire] milliseconds, TTL for the redis key
|
|
10
|
-
* @returns {boolean} true: success, false: failed
|
|
11
|
-
*/
|
|
12
|
-
async tryLock(name, expire) {
|
|
13
|
-
const result = await this.set(this._getLockKey(name), '_lock_', 'PX', expire, 'NX');
|
|
14
|
-
return result !== null;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* lock, automatically retrying if failed
|
|
18
|
-
* @param {string} name redis-lock name
|
|
19
|
-
* @param {object} [options] Options
|
|
20
|
-
* @param {number} [options.expire=60000] TTL
|
|
21
|
-
* @param {number} [options.retryInterval=100] milliseconds, the interval to retry if failed
|
|
22
|
-
* @param {number} [options.maxRetries=10] max times to retry
|
|
23
|
-
*/
|
|
24
|
-
async lock(name, options) {
|
|
25
|
-
const expire = (0, putil_varhelpers_1.toNumberDef)(options?.expire, 60000);
|
|
26
|
-
const retryInterval = (0, putil_varhelpers_1.toNumberDef)(options?.retryInterval, 100);
|
|
27
|
-
const maxRetries = (0, putil_varhelpers_1.toNumberDef)(options?.maxRetries, 10);
|
|
28
|
-
let retryTimes = 0;
|
|
29
|
-
// eslint-disable-next-line no-constant-condition
|
|
30
|
-
while (1) {
|
|
31
|
-
if (await this.tryLock(name, expire)) {
|
|
32
|
-
break;
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
await sleepAsync(retryInterval);
|
|
36
|
-
if (retryTimes >= maxRetries) {
|
|
37
|
-
throw new Error(`Redis lock "${name}" timed out`);
|
|
38
|
-
}
|
|
39
|
-
retryTimes++;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Unlock a redis-lock by name
|
|
45
|
-
* @param {string} name redis-lock name
|
|
46
|
-
*/
|
|
47
|
-
async unlock(name) {
|
|
48
|
-
const s = 'if redis.call(\'get\', KEYS[1]) == ARGV[1] then return redis.call(\'del\', KEYS[1]) else return 0 end';
|
|
49
|
-
await this.eval(s, 1, this._getLockKey(name), '_lock_');
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Set TTL for a redis-lock
|
|
53
|
-
* @param {string} name redis-lock name
|
|
54
|
-
* @param {number} milliseconds TTL
|
|
55
|
-
*/
|
|
56
|
-
async setLockTTL(name, milliseconds) {
|
|
57
|
-
const result = await this.pexpire(this._getLockKey(name), milliseconds);
|
|
58
|
-
return !!result;
|
|
59
|
-
}
|
|
60
|
-
_getLockKey(name) {
|
|
61
|
-
return (this.lockPrefix || 'lock:') + name;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
exports.RedisLock = RedisLock;
|
|
65
|
-
async function sleepAsync(ms) {
|
|
66
|
-
return new Promise(resolve => setTimeout(resolve, Number(ms)));
|
|
67
|
-
}
|
|
68
|
-
//# sourceMappingURL=redis-lock.js.map
|
package/cjs/redis-lock.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"redis-lock.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis-lock.ts"],"names":[],"mappings":";;;AACA,uDAA+C;AAU/C,MAAa,SAAS;IAIpB;;;;;OAKG;IACI,KAAK,CAAC,OAAO,CAAa,IAAI,EAAE,MAAM;QAC3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACpF,OAAO,MAAM,KAAK,IAAI,CAAC;IACzB,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,IAAI,CAAa,IAAY,EAAE,OAAqB;QAC/D,MAAM,MAAM,GAAG,IAAA,8BAAW,EAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACnD,MAAM,aAAa,GAAG,IAAA,8BAAW,EAAC,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,IAAA,8BAAW,EAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAExD,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,iDAAiD;QACjD,OAAO,CAAC,EAAE;YACR,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;gBACpC,MAAM;aACP;iBAAM;gBACL,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;gBAChC,IAAI,UAAU,IAAI,UAAU,EAAE;oBAC5B,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,aAAa,CAAC,CAAC;iBACnD;gBACD,UAAU,EAAE,CAAC;aACd;SACF;IACH,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,MAAM,CAAa,IAAI;QAClC,MAAM,CAAC,GAAG,uGAAuG,CAAC;QAClH,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC1D,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,UAAU,CAAa,IAAI,EAAE,YAAY;QACpD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;QACxE,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAEO,WAAW,CAAC,IAAI;QACtB,OAAO,CAAC,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7C,CAAC;CAEF;AAlED,8BAkEC;AAED,KAAK,UAAU,UAAU,CAAC,EAAU;IAClC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
|
package/esm/redis-lock.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { toNumberDef } from 'putil-varhelpers';
|
|
2
|
-
export class RedisLock {
|
|
3
|
-
/**
|
|
4
|
-
* Try to lock once
|
|
5
|
-
* @param {string} name redis-lock name
|
|
6
|
-
* @param {number} [expire] milliseconds, TTL for the redis key
|
|
7
|
-
* @returns {boolean} true: success, false: failed
|
|
8
|
-
*/
|
|
9
|
-
async tryLock(name, expire) {
|
|
10
|
-
const result = await this.set(this._getLockKey(name), '_lock_', 'PX', expire, 'NX');
|
|
11
|
-
return result !== null;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* lock, automatically retrying if failed
|
|
15
|
-
* @param {string} name redis-lock name
|
|
16
|
-
* @param {object} [options] Options
|
|
17
|
-
* @param {number} [options.expire=60000] TTL
|
|
18
|
-
* @param {number} [options.retryInterval=100] milliseconds, the interval to retry if failed
|
|
19
|
-
* @param {number} [options.maxRetries=10] max times to retry
|
|
20
|
-
*/
|
|
21
|
-
async lock(name, options) {
|
|
22
|
-
const expire = toNumberDef(options?.expire, 60000);
|
|
23
|
-
const retryInterval = toNumberDef(options?.retryInterval, 100);
|
|
24
|
-
const maxRetries = toNumberDef(options?.maxRetries, 10);
|
|
25
|
-
let retryTimes = 0;
|
|
26
|
-
// eslint-disable-next-line no-constant-condition
|
|
27
|
-
while (1) {
|
|
28
|
-
if (await this.tryLock(name, expire)) {
|
|
29
|
-
break;
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
await sleepAsync(retryInterval);
|
|
33
|
-
if (retryTimes >= maxRetries) {
|
|
34
|
-
throw new Error(`Redis lock "${name}" timed out`);
|
|
35
|
-
}
|
|
36
|
-
retryTimes++;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Unlock a redis-lock by name
|
|
42
|
-
* @param {string} name redis-lock name
|
|
43
|
-
*/
|
|
44
|
-
async unlock(name) {
|
|
45
|
-
const s = 'if redis.call(\'get\', KEYS[1]) == ARGV[1] then return redis.call(\'del\', KEYS[1]) else return 0 end';
|
|
46
|
-
await this.eval(s, 1, this._getLockKey(name), '_lock_');
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Set TTL for a redis-lock
|
|
50
|
-
* @param {string} name redis-lock name
|
|
51
|
-
* @param {number} milliseconds TTL
|
|
52
|
-
*/
|
|
53
|
-
async setLockTTL(name, milliseconds) {
|
|
54
|
-
const result = await this.pexpire(this._getLockKey(name), milliseconds);
|
|
55
|
-
return !!result;
|
|
56
|
-
}
|
|
57
|
-
_getLockKey(name) {
|
|
58
|
-
return (this.lockPrefix || 'lock:') + name;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
async function sleepAsync(ms) {
|
|
62
|
-
return new Promise(resolve => setTimeout(resolve, Number(ms)));
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=redis-lock.js.map
|
package/esm/redis-lock.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"redis-lock.js","sourceRoot":"","sources":["../../../packages/ioredis/src/redis-lock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAU/C,MAAM,OAAO,SAAS;IAIpB;;;;;OAKG;IACI,KAAK,CAAC,OAAO,CAAa,IAAI,EAAE,MAAM;QAC3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACpF,OAAO,MAAM,KAAK,IAAI,CAAC;IACzB,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,IAAI,CAAa,IAAY,EAAE,OAAqB;QAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACnD,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAExD,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,iDAAiD;QACjD,OAAO,CAAC,EAAE;YACR,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;gBACpC,MAAM;aACP;iBAAM;gBACL,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;gBAChC,IAAI,UAAU,IAAI,UAAU,EAAE;oBAC5B,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,aAAa,CAAC,CAAC;iBACnD;gBACD,UAAU,EAAE,CAAC;aACd;SACF;IACH,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,MAAM,CAAa,IAAI;QAClC,MAAM,CAAC,GAAG,uGAAuG,CAAC;QAClH,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC1D,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,UAAU,CAAa,IAAI,EAAE,YAAY;QACpD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;QACxE,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAEO,WAAW,CAAC,IAAI;QACtB,OAAO,CAAC,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,IAAI,CAAC;IAC7C,CAAC;CAEF;AAED,KAAK,UAAU,UAAU,CAAC,EAAU;IAClC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
|
package/types/redis-lock.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import Redis, { Cluster } from 'ioredis';
|
|
2
|
-
export interface LockOptions {
|
|
3
|
-
expire?: number;
|
|
4
|
-
retryInterval?: number;
|
|
5
|
-
maxRetries?: number;
|
|
6
|
-
}
|
|
7
|
-
type This = RedisLock & (Redis | Cluster);
|
|
8
|
-
export declare class RedisLock {
|
|
9
|
-
lockPrefix?: string;
|
|
10
|
-
/**
|
|
11
|
-
* Try to lock once
|
|
12
|
-
* @param {string} name redis-lock name
|
|
13
|
-
* @param {number} [expire] milliseconds, TTL for the redis key
|
|
14
|
-
* @returns {boolean} true: success, false: failed
|
|
15
|
-
*/
|
|
16
|
-
tryLock(this: This, name: any, expire: any): Promise<boolean>;
|
|
17
|
-
/**
|
|
18
|
-
* lock, automatically retrying if failed
|
|
19
|
-
* @param {string} name redis-lock name
|
|
20
|
-
* @param {object} [options] Options
|
|
21
|
-
* @param {number} [options.expire=60000] TTL
|
|
22
|
-
* @param {number} [options.retryInterval=100] milliseconds, the interval to retry if failed
|
|
23
|
-
* @param {number} [options.maxRetries=10] max times to retry
|
|
24
|
-
*/
|
|
25
|
-
lock(this: This, name: string, options?: LockOptions): Promise<void>;
|
|
26
|
-
/**
|
|
27
|
-
* Unlock a redis-lock by name
|
|
28
|
-
* @param {string} name redis-lock name
|
|
29
|
-
*/
|
|
30
|
-
unlock(this: This, name: any): Promise<void>;
|
|
31
|
-
/**
|
|
32
|
-
* Set TTL for a redis-lock
|
|
33
|
-
* @param {string} name redis-lock name
|
|
34
|
-
* @param {number} milliseconds TTL
|
|
35
|
-
*/
|
|
36
|
-
setLockTTL(this: This, name: any, milliseconds: any): Promise<boolean>;
|
|
37
|
-
private _getLockKey;
|
|
38
|
-
}
|
|
39
|
-
export {};
|