redis-smq-common 1.0.1 → 1.0.4
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 +20 -0
- package/dist/src/lock-manager/errors/lock-manager-method-not-allowed.error.d.ts +4 -0
- package/dist/src/lock-manager/errors/lock-manager-method-not-allowed.error.js +11 -0
- package/dist/src/lock-manager/errors/lock-manager-not-acquired.error.d.ts +4 -0
- package/dist/src/lock-manager/errors/lock-manager-not-acquired.error.js +11 -0
- package/dist/src/lock-manager/errors/lock-manager-not-released.error.d.ts +4 -0
- package/dist/src/lock-manager/errors/lock-manager-not-released.error.js +11 -0
- package/dist/src/lock-manager/lock-manager.d.ts +8 -4
- package/dist/src/lock-manager/lock-manager.js +55 -20
- package/dist/src/redis-client/clients/ioredis-client.d.ts +5 -0
- package/dist/src/redis-client/clients/ioredis-client.js +25 -0
- package/dist/src/redis-client/clients/node-redis-v3-client.d.ts +5 -0
- package/dist/src/redis-client/clients/node-redis-v3-client.js +25 -0
- package/dist/src/redis-client/clients/node-redis-v4-client.d.ts +5 -0
- package/dist/src/redis-client/clients/node-redis-v4-client.js +27 -0
- package/dist/src/redis-client/redis-client.d.ts +7 -1
- package/dist/src/redis-client/redis-client.js +6 -0
- package/dist/src/worker/worker-runner/worker-runner.js +7 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 1.0.4 (2022-08-24)
|
|
4
|
+
|
|
5
|
+
* test(redis-client): cover srem command (caf3837)
|
|
6
|
+
* feat(redis-client): add support for srem command (7ddaf24)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## 1.0.3 (2022-08-16)
|
|
10
|
+
|
|
11
|
+
* [RedisClient] Update tests (6f1fd51)
|
|
12
|
+
* [RedisClient] Make validateRedisVersion() public (c2fccb3)
|
|
13
|
+
* [RedisClient] Support MATCH and COUNT options for sscan (12b24ac)
|
|
14
|
+
* [RedisClient] Fallback to smembers when sscan is not supported (8a4409f)
|
|
15
|
+
* [RedisClient] Test sscan command (17b8279)
|
|
16
|
+
* [RedisClient] Add sscan command (b771873)
|
|
17
|
+
|
|
18
|
+
## 1.0.2 (2022-08-10)
|
|
19
|
+
|
|
20
|
+
* Update LockManager tests (321c8c4)
|
|
21
|
+
* Fix "LockManagerExtendError: Acquired lock could not be extended" (fa3a8e5)
|
|
22
|
+
|
|
3
23
|
## 1.0.1 (2022-07-07)
|
|
4
24
|
|
|
5
25
|
* Remove unused WorkerRunnerError (48e7206)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LockManagerMethodNotAllowedError = void 0;
|
|
4
|
+
const lock_manager_error_1 = require("./lock-manager.error");
|
|
5
|
+
class LockManagerMethodNotAllowedError extends lock_manager_error_1.LockManagerError {
|
|
6
|
+
constructor(message = `This method can not be used when autoExtend is enabled`) {
|
|
7
|
+
super(message);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.LockManagerMethodNotAllowedError = LockManagerMethodNotAllowedError;
|
|
11
|
+
//# sourceMappingURL=lock-manager-method-not-allowed.error.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LockManagerNotAcquiredError = void 0;
|
|
4
|
+
const lock_manager_error_1 = require("./lock-manager.error");
|
|
5
|
+
class LockManagerNotAcquiredError extends lock_manager_error_1.LockManagerError {
|
|
6
|
+
constructor(message = `Can not extend a lock which has not been yet acquired. Maybe a pending operation is in progress.`) {
|
|
7
|
+
super(message);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.LockManagerNotAcquiredError = LockManagerNotAcquiredError;
|
|
11
|
+
//# sourceMappingURL=lock-manager-not-acquired.error.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LockManagerNotReleasedError = void 0;
|
|
4
|
+
const lock_manager_error_1 = require("./lock-manager.error");
|
|
5
|
+
class LockManagerNotReleasedError extends lock_manager_error_1.LockManagerError {
|
|
6
|
+
constructor(message = `A lock has been already obtained but not yet released or maybe a pending operation is in progress.`) {
|
|
7
|
+
super(message);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.LockManagerNotReleasedError = LockManagerNotReleasedError;
|
|
11
|
+
//# sourceMappingURL=lock-manager-not-released.error.js.map
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { ICallback } from '../../types';
|
|
3
3
|
import { RedisClient } from '../redis-client/redis-client';
|
|
4
|
-
declare enum ELockStatus {
|
|
4
|
+
export declare enum ELockStatus {
|
|
5
5
|
unlocked = 0,
|
|
6
6
|
locking = 1,
|
|
7
7
|
locked = 2,
|
|
8
8
|
releasing = 3,
|
|
9
|
-
extending = 4
|
|
9
|
+
extending = 4,
|
|
10
|
+
extended = 5
|
|
10
11
|
}
|
|
11
12
|
export declare enum ELuaScript {
|
|
12
13
|
RELEASE_LOCK = "RELEASE_LOCK",
|
|
@@ -22,16 +23,19 @@ export declare class LockManager {
|
|
|
22
23
|
protected status: ELockStatus;
|
|
23
24
|
protected lockingTimer: NodeJS.Timeout | null;
|
|
24
25
|
protected autoExtendTimer: NodeJS.Timeout | null;
|
|
25
|
-
|
|
26
|
+
protected throwExceptions: boolean;
|
|
27
|
+
constructor(redisClient: RedisClient, lockKey: string, ttl: number, retryOnFail?: boolean, autoExtend?: boolean, throwExceptions?: boolean);
|
|
26
28
|
protected resetTimers(): void;
|
|
27
29
|
protected setUnlocked(): void;
|
|
28
30
|
protected setLocked(): void;
|
|
31
|
+
protected setExtended(): void;
|
|
29
32
|
protected extend(cb: ICallback<void>): void;
|
|
30
33
|
protected runAutoExtendTimer(): void;
|
|
31
34
|
acquireLock(cb: ICallback<void>): void;
|
|
32
35
|
extendLock(cb: ICallback<void>): void;
|
|
33
36
|
releaseLock(cb: ICallback<void>): void;
|
|
37
|
+
acquireOrExtend(cb: ICallback<ELockStatus>): void;
|
|
34
38
|
isLocked(): boolean;
|
|
39
|
+
isReleased(): boolean;
|
|
35
40
|
getId(): string;
|
|
36
41
|
}
|
|
37
|
-
export {};
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LockManager = exports.ELuaScript = void 0;
|
|
3
|
+
exports.LockManager = exports.ELuaScript = exports.ELockStatus = void 0;
|
|
4
4
|
const redis_client_1 = require("../redis-client/redis-client");
|
|
5
5
|
const uuid_1 = require("uuid");
|
|
6
|
-
const lock_manager_error_1 = require("./errors/lock-manager.error");
|
|
7
6
|
const lock_manager_abort_error_1 = require("./errors/lock-manager-abort.error");
|
|
8
7
|
const lock_manager_extend_error_1 = require("./errors/lock-manager-extend.error");
|
|
9
8
|
const lock_manager_acquire_error_1 = require("./errors/lock-manager-acquire.error");
|
|
10
9
|
const fs = require("fs");
|
|
10
|
+
const lock_manager_method_not_allowed_error_1 = require("./errors/lock-manager-method-not-allowed.error");
|
|
11
|
+
const lock_manager_not_acquired_error_1 = require("./errors/lock-manager-not-acquired.error");
|
|
12
|
+
const lock_manager_not_released_error_1 = require("./errors/lock-manager-not-released.error");
|
|
11
13
|
var ELockStatus;
|
|
12
14
|
(function (ELockStatus) {
|
|
13
15
|
ELockStatus[ELockStatus["unlocked"] = 0] = "unlocked";
|
|
@@ -15,7 +17,8 @@ var ELockStatus;
|
|
|
15
17
|
ELockStatus[ELockStatus["locked"] = 2] = "locked";
|
|
16
18
|
ELockStatus[ELockStatus["releasing"] = 3] = "releasing";
|
|
17
19
|
ELockStatus[ELockStatus["extending"] = 4] = "extending";
|
|
18
|
-
|
|
20
|
+
ELockStatus[ELockStatus["extended"] = 5] = "extended";
|
|
21
|
+
})(ELockStatus = exports.ELockStatus || (exports.ELockStatus = {}));
|
|
19
22
|
var ELuaScript;
|
|
20
23
|
(function (ELuaScript) {
|
|
21
24
|
ELuaScript["RELEASE_LOCK"] = "RELEASE_LOCK";
|
|
@@ -24,16 +27,18 @@ var ELuaScript;
|
|
|
24
27
|
redis_client_1.RedisClient.addScript(ELuaScript.RELEASE_LOCK, fs.readFileSync(`${__dirname}/redis-client/lua/release-lock.lua`).toString());
|
|
25
28
|
redis_client_1.RedisClient.addScript(ELuaScript.EXTEND_LOCK, fs.readFileSync(`${__dirname}/redis-client/lua/extend-lock.lua`).toString());
|
|
26
29
|
class LockManager {
|
|
27
|
-
constructor(redisClient, lockKey, ttl, retryOnFail = false, autoExtend = false) {
|
|
30
|
+
constructor(redisClient, lockKey, ttl, retryOnFail = false, autoExtend = false, throwExceptions = true) {
|
|
28
31
|
this.status = ELockStatus.unlocked;
|
|
29
32
|
this.lockingTimer = null;
|
|
30
33
|
this.autoExtendTimer = null;
|
|
34
|
+
this.throwExceptions = true;
|
|
31
35
|
this.lockKey = lockKey;
|
|
32
36
|
this.ttl = ttl;
|
|
33
37
|
this.retryOnFail = retryOnFail;
|
|
34
38
|
this.lockId = (0, uuid_1.v4)();
|
|
35
39
|
this.redisClient = redisClient;
|
|
36
40
|
this.autoExtend = autoExtend;
|
|
41
|
+
this.throwExceptions = throwExceptions;
|
|
37
42
|
}
|
|
38
43
|
resetTimers() {
|
|
39
44
|
if (this.lockingTimer) {
|
|
@@ -51,10 +56,12 @@ class LockManager {
|
|
|
51
56
|
setLocked() {
|
|
52
57
|
this.status = ELockStatus.locked;
|
|
53
58
|
}
|
|
59
|
+
setExtended() {
|
|
60
|
+
this.status = ELockStatus.extended;
|
|
61
|
+
}
|
|
54
62
|
extend(cb) {
|
|
55
|
-
if (this.
|
|
56
|
-
cb(new
|
|
57
|
-
}
|
|
63
|
+
if (!this.isLocked())
|
|
64
|
+
cb(new lock_manager_not_acquired_error_1.LockManagerNotAcquiredError());
|
|
58
65
|
else {
|
|
59
66
|
this.status = ELockStatus.extending;
|
|
60
67
|
this.redisClient.runScript(ELuaScript.EXTEND_LOCK, [this.lockKey], [this.lockId, this.ttl], (err, reply) => {
|
|
@@ -67,7 +74,7 @@ class LockManager {
|
|
|
67
74
|
cb(new lock_manager_extend_error_1.LockManagerExtendError());
|
|
68
75
|
}
|
|
69
76
|
else {
|
|
70
|
-
this.
|
|
77
|
+
this.setExtended();
|
|
71
78
|
cb();
|
|
72
79
|
}
|
|
73
80
|
}
|
|
@@ -83,14 +90,14 @@ class LockManager {
|
|
|
83
90
|
this.autoExtendTimer = setTimeout(() => this.extend((err) => {
|
|
84
91
|
if (!err)
|
|
85
92
|
this.runAutoExtendTimer();
|
|
86
|
-
else if (
|
|
93
|
+
else if (this.throwExceptions &&
|
|
94
|
+
!(err instanceof lock_manager_abort_error_1.LockManagerAbortError))
|
|
87
95
|
throw err;
|
|
88
96
|
}), ms);
|
|
89
97
|
}
|
|
90
98
|
acquireLock(cb) {
|
|
91
|
-
if (this.
|
|
92
|
-
cb(new
|
|
93
|
-
}
|
|
99
|
+
if (!this.isReleased())
|
|
100
|
+
cb(new lock_manager_not_released_error_1.LockManagerNotReleasedError());
|
|
94
101
|
else {
|
|
95
102
|
this.status = ELockStatus.locking;
|
|
96
103
|
const lock = () => {
|
|
@@ -134,18 +141,17 @@ class LockManager {
|
|
|
134
141
|
}
|
|
135
142
|
}
|
|
136
143
|
extendLock(cb) {
|
|
137
|
-
if (this.autoExtend)
|
|
138
|
-
cb(new
|
|
139
|
-
}
|
|
144
|
+
if (this.autoExtend)
|
|
145
|
+
cb(new lock_manager_method_not_allowed_error_1.LockManagerMethodNotAllowedError());
|
|
140
146
|
else
|
|
141
147
|
this.extend(cb);
|
|
142
148
|
}
|
|
143
149
|
releaseLock(cb) {
|
|
144
150
|
const status = this.status;
|
|
145
|
-
if (status === ELockStatus.
|
|
146
|
-
cb(new lock_manager_error_1.LockManagerError('A pending releaseLock() call is in progress'));
|
|
147
|
-
else if (status === ELockStatus.unlocked)
|
|
151
|
+
if (status === ELockStatus.unlocked)
|
|
148
152
|
cb();
|
|
153
|
+
else if (!this.isLocked())
|
|
154
|
+
cb(new lock_manager_not_acquired_error_1.LockManagerNotAcquiredError());
|
|
149
155
|
else {
|
|
150
156
|
this.resetTimers();
|
|
151
157
|
this.status = ELockStatus.releasing;
|
|
@@ -159,9 +165,38 @@ class LockManager {
|
|
|
159
165
|
});
|
|
160
166
|
}
|
|
161
167
|
}
|
|
168
|
+
acquireOrExtend(cb) {
|
|
169
|
+
if (this.autoExtend)
|
|
170
|
+
cb(new lock_manager_method_not_allowed_error_1.LockManagerMethodNotAllowedError());
|
|
171
|
+
else {
|
|
172
|
+
const lock = () => {
|
|
173
|
+
this.acquireLock((err) => {
|
|
174
|
+
if (err)
|
|
175
|
+
cb(err);
|
|
176
|
+
else
|
|
177
|
+
cb(null, ELockStatus.locked);
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
if (this.isLocked())
|
|
181
|
+
this.extend((err) => {
|
|
182
|
+
if (err) {
|
|
183
|
+
if (err instanceof lock_manager_extend_error_1.LockManagerExtendError)
|
|
184
|
+
lock();
|
|
185
|
+
else
|
|
186
|
+
cb(err);
|
|
187
|
+
}
|
|
188
|
+
else
|
|
189
|
+
cb(null, ELockStatus.extended);
|
|
190
|
+
});
|
|
191
|
+
else
|
|
192
|
+
lock();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
162
195
|
isLocked() {
|
|
163
|
-
return (this.status === ELockStatus.locked ||
|
|
164
|
-
|
|
196
|
+
return (this.status === ELockStatus.locked || this.status === ELockStatus.extended);
|
|
197
|
+
}
|
|
198
|
+
isReleased() {
|
|
199
|
+
return this.status === ELockStatus.unlocked;
|
|
165
200
|
}
|
|
166
201
|
getId() {
|
|
167
202
|
return this.lockId;
|
|
@@ -17,6 +17,10 @@ export declare class IoredisClient extends RedisClient {
|
|
|
17
17
|
watch(args: string[], cb: ICallback<string>): void;
|
|
18
18
|
unwatch(cb: ICallback<string>): void;
|
|
19
19
|
sismember(key: string, member: string, cb: ICallback<number>): void;
|
|
20
|
+
sscan(key: string, options: {
|
|
21
|
+
MATCH?: string;
|
|
22
|
+
COUNT?: number;
|
|
23
|
+
}, cb: ICallback<string[]>): void;
|
|
20
24
|
zcard(key: string, cb: ICallback<number>): void;
|
|
21
25
|
zrange(key: string, min: number, max: number, cb: ICallback<string[]>): void;
|
|
22
26
|
psubscribe(pattern: string): void;
|
|
@@ -26,6 +30,7 @@ export declare class IoredisClient extends RedisClient {
|
|
|
26
30
|
zrangebyscore(key: string, min: number | string, max: number | string, cb: ICallback<string[]>): void;
|
|
27
31
|
smembers(key: string, cb: ICallback<string[]>): void;
|
|
28
32
|
sadd(key: string, member: string, cb: ICallback<number>): void;
|
|
33
|
+
srem(key: string, member: string, cb: ICallback<number>): void;
|
|
29
34
|
hgetall(key: string, cb: ICallback<Record<string, string>>): void;
|
|
30
35
|
hget(key: string, field: string, cb: ICallback<string | null>): void;
|
|
31
36
|
hset(key: string, field: string, value: string, cb: ICallback<number>): void;
|
|
@@ -47,6 +47,28 @@ class IoredisClient extends redis_client_1.RedisClient {
|
|
|
47
47
|
sismember(key, member, cb) {
|
|
48
48
|
this.client.sismember(key, member, cb);
|
|
49
49
|
}
|
|
50
|
+
sscan(key, options, cb) {
|
|
51
|
+
const result = new Set();
|
|
52
|
+
const iterate = (position) => {
|
|
53
|
+
const args = [key, position];
|
|
54
|
+
if (options.MATCH)
|
|
55
|
+
args.push('MATCH', options.MATCH);
|
|
56
|
+
if (options.COUNT)
|
|
57
|
+
args.push('COUNT', String(options.COUNT));
|
|
58
|
+
this.client.sscan(...args, (err, [cursor, items]) => {
|
|
59
|
+
if (err)
|
|
60
|
+
cb(err);
|
|
61
|
+
else {
|
|
62
|
+
items.forEach((i) => result.add(i));
|
|
63
|
+
if (cursor === '0')
|
|
64
|
+
cb(null, [...result]);
|
|
65
|
+
else
|
|
66
|
+
iterate(cursor);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
iterate('0');
|
|
71
|
+
}
|
|
50
72
|
zcard(key, cb) {
|
|
51
73
|
this.client.zcard(key, cb);
|
|
52
74
|
}
|
|
@@ -74,6 +96,9 @@ class IoredisClient extends redis_client_1.RedisClient {
|
|
|
74
96
|
sadd(key, member, cb) {
|
|
75
97
|
this.client.sadd(key, member, cb);
|
|
76
98
|
}
|
|
99
|
+
srem(key, member, cb) {
|
|
100
|
+
this.client.srem(key, member, cb);
|
|
101
|
+
}
|
|
77
102
|
hgetall(key, cb) {
|
|
78
103
|
this.client.hgetall(key, cb);
|
|
79
104
|
}
|
|
@@ -17,6 +17,10 @@ export declare class NodeRedisV3Client extends RedisClient {
|
|
|
17
17
|
watch(args: string[], cb: ICallback<string>): void;
|
|
18
18
|
unwatch(cb: ICallback<string>): void;
|
|
19
19
|
sismember(key: string, member: string, cb: ICallback<number>): void;
|
|
20
|
+
sscan(key: string, options: {
|
|
21
|
+
MATCH?: string;
|
|
22
|
+
COUNT?: number;
|
|
23
|
+
}, cb: ICallback<string[]>): void;
|
|
20
24
|
zcard(key: string, cb: ICallback<number>): void;
|
|
21
25
|
zrange(key: string, min: number, max: number, cb: ICallback<string[]>): void;
|
|
22
26
|
psubscribe(pattern: string): void;
|
|
@@ -26,6 +30,7 @@ export declare class NodeRedisV3Client extends RedisClient {
|
|
|
26
30
|
zrangebyscore(key: string, min: number | string, max: number | string, cb: ICallback<string[]>): void;
|
|
27
31
|
smembers(key: string, cb: ICallback<string[]>): void;
|
|
28
32
|
sadd(key: string, member: string, cb: ICallback<number>): void;
|
|
33
|
+
srem(key: string, member: string, cb: ICallback<number>): void;
|
|
29
34
|
hgetall(key: string, cb: ICallback<Record<string, string>>): void;
|
|
30
35
|
hget(key: string, field: string, cb: ICallback<string | null>): void;
|
|
31
36
|
hset(key: string, field: string, value: string, cb: ICallback<number>): void;
|
|
@@ -74,6 +74,28 @@ class NodeRedisV3Client extends redis_client_1.RedisClient {
|
|
|
74
74
|
sismember(key, member, cb) {
|
|
75
75
|
this.client.sismember(key, member, cb);
|
|
76
76
|
}
|
|
77
|
+
sscan(key, options, cb) {
|
|
78
|
+
const result = new Set();
|
|
79
|
+
const iterate = (position) => {
|
|
80
|
+
const args = [key, position];
|
|
81
|
+
if (options.MATCH)
|
|
82
|
+
args.push('MATCH', options.MATCH);
|
|
83
|
+
if (options.COUNT)
|
|
84
|
+
args.push('COUNT', String(options.COUNT));
|
|
85
|
+
this.client.sscan(...args, (err, [cursor, items]) => {
|
|
86
|
+
if (err)
|
|
87
|
+
cb(err);
|
|
88
|
+
else {
|
|
89
|
+
items.forEach((i) => result.add(i));
|
|
90
|
+
if (cursor === '0')
|
|
91
|
+
cb(null, [...result]);
|
|
92
|
+
else
|
|
93
|
+
iterate(cursor);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
iterate('0');
|
|
98
|
+
}
|
|
77
99
|
zcard(key, cb) {
|
|
78
100
|
this.client.zcard(key, cb);
|
|
79
101
|
}
|
|
@@ -101,6 +123,9 @@ class NodeRedisV3Client extends redis_client_1.RedisClient {
|
|
|
101
123
|
sadd(key, member, cb) {
|
|
102
124
|
this.client.sadd(key, member, cb);
|
|
103
125
|
}
|
|
126
|
+
srem(key, member, cb) {
|
|
127
|
+
this.client.srem(key, member, cb);
|
|
128
|
+
}
|
|
104
129
|
hgetall(key, cb) {
|
|
105
130
|
this.client.hgetall(key, (err, reply) => {
|
|
106
131
|
if (err)
|
|
@@ -25,7 +25,12 @@ export declare class NodeRedisV4Client extends RedisClient {
|
|
|
25
25
|
unsubscribe(channel: string): void;
|
|
26
26
|
zrangebyscore(key: string, min: number | string, max: number | string, cb: ICallback<string[]>): void;
|
|
27
27
|
smembers(key: string, cb: ICallback<string[]>): void;
|
|
28
|
+
sscan(key: string, options: {
|
|
29
|
+
MATCH?: string;
|
|
30
|
+
COUNT?: number;
|
|
31
|
+
}, cb: ICallback<string[]>): void;
|
|
28
32
|
sadd(key: string, member: string, cb: ICallback<number>): void;
|
|
33
|
+
srem(key: string, member: string, cb: ICallback<number>): void;
|
|
29
34
|
hgetall(key: string, cb: ICallback<Record<string, string>>): void;
|
|
30
35
|
hget(key: string, field: string, cb: ICallback<string | null>): void;
|
|
31
36
|
hset(key: string, field: string, value: string, cb: ICallback<number>): void;
|
|
@@ -94,12 +94,39 @@ class NodeRedisV4Client extends redis_client_1.RedisClient {
|
|
|
94
94
|
.then((reply) => cb(null, reply))
|
|
95
95
|
.catch(cb);
|
|
96
96
|
}
|
|
97
|
+
sscan(key, options, cb) {
|
|
98
|
+
const result = new Set();
|
|
99
|
+
const iterate = (position) => {
|
|
100
|
+
const args = [
|
|
101
|
+
key,
|
|
102
|
+
position,
|
|
103
|
+
options,
|
|
104
|
+
];
|
|
105
|
+
this.client
|
|
106
|
+
.sScan(...args)
|
|
107
|
+
.then(({ cursor, members }) => {
|
|
108
|
+
members.forEach((i) => result.add(i));
|
|
109
|
+
if (cursor === 0)
|
|
110
|
+
cb(null, [...result]);
|
|
111
|
+
else
|
|
112
|
+
iterate(cursor);
|
|
113
|
+
})
|
|
114
|
+
.catch(cb);
|
|
115
|
+
};
|
|
116
|
+
iterate(0);
|
|
117
|
+
}
|
|
97
118
|
sadd(key, member, cb) {
|
|
98
119
|
this.client
|
|
99
120
|
.sAdd(key, member)
|
|
100
121
|
.then((reply) => cb(null, reply))
|
|
101
122
|
.catch(cb);
|
|
102
123
|
}
|
|
124
|
+
srem(key, member, cb) {
|
|
125
|
+
this.client
|
|
126
|
+
.sRem(key, member)
|
|
127
|
+
.then((reply) => cb(null, reply))
|
|
128
|
+
.catch(cb);
|
|
129
|
+
}
|
|
103
130
|
hgetall(key, cb) {
|
|
104
131
|
this.client
|
|
105
132
|
.hGetAll(key)
|
|
@@ -12,7 +12,7 @@ export declare abstract class RedisClient extends EventEmitter {
|
|
|
12
12
|
protected static scriptsLoaded: boolean;
|
|
13
13
|
protected static luaScripts: LuaScripts;
|
|
14
14
|
protected connectionClosed: boolean;
|
|
15
|
-
|
|
15
|
+
validateRedisVersion(major: number, feature?: number, minor?: number): boolean;
|
|
16
16
|
abstract set(key: string, value: string, options: {
|
|
17
17
|
expire?: {
|
|
18
18
|
mode: 'EX' | 'PX';
|
|
@@ -33,7 +33,13 @@ export declare abstract class RedisClient extends EventEmitter {
|
|
|
33
33
|
abstract unsubscribe(channel: string): void;
|
|
34
34
|
abstract zrangebyscore(key: string, min: number | string, max: number | string, cb: ICallback<string[]>): void;
|
|
35
35
|
abstract smembers(key: string, cb: ICallback<string[]>): void;
|
|
36
|
+
abstract sscan(key: string, options: {
|
|
37
|
+
MATCH?: string;
|
|
38
|
+
COUNT?: number;
|
|
39
|
+
}, cb: ICallback<string[]>): void;
|
|
40
|
+
sscanFallback(key: string, cb: ICallback<string[]>): void;
|
|
36
41
|
abstract sadd(key: string, member: string, cb: ICallback<number>): void;
|
|
42
|
+
abstract srem(key: string, member: string, cb: ICallback<number>): void;
|
|
37
43
|
abstract hgetall(key: string, cb: ICallback<Record<string, string>>): void;
|
|
38
44
|
abstract hget(key: string, field: string, cb: ICallback<string | null>): void;
|
|
39
45
|
abstract hset(key: string, field: string, value: string, cb: ICallback<number>): void;
|
|
@@ -25,6 +25,12 @@ class RedisClient extends events_1.EventEmitter {
|
|
|
25
25
|
RedisClient.redisServerVersion[1] >= feature &&
|
|
26
26
|
RedisClient.redisServerVersion[2] >= minor));
|
|
27
27
|
}
|
|
28
|
+
sscanFallback(key, cb) {
|
|
29
|
+
if (this.validateRedisVersion(2, 8))
|
|
30
|
+
this.sscan(key, {}, cb);
|
|
31
|
+
else
|
|
32
|
+
this.smembers(key, cb);
|
|
33
|
+
}
|
|
28
34
|
zpophgetrpush(source, sourceHash, destination, cb) {
|
|
29
35
|
this.runScript(ELuaScriptName.ZPOPHGETRPUSH, [source, sourceHash, destination], [], (err, res) => {
|
|
30
36
|
if (err)
|
|
@@ -14,16 +14,12 @@ class WorkerRunner extends events_1.EventEmitter {
|
|
|
14
14
|
this.onTick = () => {
|
|
15
15
|
async_1.async.waterfall([
|
|
16
16
|
(cb) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
else
|
|
26
|
-
cb();
|
|
17
|
+
this.lockManager.acquireOrExtend((err, status) => {
|
|
18
|
+
if (status === lock_manager_1.ELockStatus.locked) {
|
|
19
|
+
this.logger.info(`Workers are exclusively running from this instance (Lock ID ${this.lockManager.getId()}).`);
|
|
20
|
+
}
|
|
21
|
+
cb(err);
|
|
22
|
+
});
|
|
27
23
|
},
|
|
28
24
|
(cb) => {
|
|
29
25
|
this.workerPool.work(cb);
|
|
@@ -58,7 +54,7 @@ class WorkerRunner extends events_1.EventEmitter {
|
|
|
58
54
|
this.powerManager = new power_manager_1.PowerManager();
|
|
59
55
|
this.redisClient = redisClient;
|
|
60
56
|
this.logger = logger;
|
|
61
|
-
this.lockManager = new lock_manager_1.LockManager(redisClient, keyLock,
|
|
57
|
+
this.lockManager = new lock_manager_1.LockManager(redisClient, keyLock, 60000);
|
|
62
58
|
this.ticker = new ticker_1.Ticker(this.onTick);
|
|
63
59
|
this.workerPool = workerPool;
|
|
64
60
|
}
|
package/package.json
CHANGED