redis-smq 7.2.1 → 7.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/src/lib/consumer/consumer-heartbeat.d.ts +3 -7
- package/dist/src/lib/consumer/consumer-heartbeat.js +16 -59
- package/dist/src/lib/consumer/consumer-queues.js +3 -2
- package/dist/src/lib/consumer/consumer.d.ts +6 -8
- package/dist/src/lib/consumer/consumer.js +14 -6
- package/dist/src/lib/queue-manager/delete-queue-transaction.js +2 -2
- package/dist/src/workers/schedule.worker.js +1 -1
- package/dist/src/workers/watchdog.worker.js +1 -1
- package/package.json +3 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 7.2.3 (2023-03-26)
|
|
4
|
+
|
|
5
|
+
* test(consumer-heartbeat): update tests (4332153)
|
|
6
|
+
* refactor(consumer-heartbeat): clean up and improve API (20fc1b1)
|
|
7
|
+
|
|
8
|
+
## 7.2.2 (2023-03-25)
|
|
9
|
+
|
|
10
|
+
* test(workers): update tests (c22f1bb)
|
|
11
|
+
* perf(workers): use offset/count for schedule and watchdog workers (e78ecdb)
|
|
12
|
+
* build: bump up redis-smq-common to v2.0.0 (c90050d)
|
|
13
|
+
* build: clean up (61851a9)
|
|
14
|
+
|
|
3
15
|
## 7.2.1 (2023-02-15)
|
|
4
16
|
|
|
5
17
|
* build: update deps (e362d7c)
|
|
@@ -15,12 +15,8 @@ export declare class ConsumerHeartbeat extends EventEmitter {
|
|
|
15
15
|
protected getPayload(): TConsumerHeartbeat;
|
|
16
16
|
protected onTick(): void;
|
|
17
17
|
quit(cb: ICallback<void>): void;
|
|
18
|
-
static
|
|
19
|
-
static
|
|
20
|
-
|
|
21
|
-
payload: string;
|
|
22
|
-
}[]>): void;
|
|
23
|
-
static getValidHeartbeatIds(redisClient: RedisClient, cb: ICallback<string[]>): void;
|
|
24
|
-
static getExpiredHeartbeatIds(redisClient: RedisClient, cb: ICallback<string[]>): void;
|
|
18
|
+
protected static isExpiredHeartbeat(heartbeat: TConsumerHeartbeat): boolean;
|
|
19
|
+
static getConsumersHeartbeats(redisClient: RedisClient, consumerIds: string[], cb: ICallback<Record<string, TConsumerHeartbeat | false>>): void;
|
|
20
|
+
static getExpiredHeartbeatIds(redisClient: RedisClient, offset: number, count: number, cb: ICallback<string[]>): void;
|
|
25
21
|
static handleExpiredHeartbeatId(consumerId: string | string[], multi: IRedisClientMulti): void;
|
|
26
22
|
}
|
|
@@ -84,7 +84,12 @@ class ConsumerHeartbeat extends events_2.EventEmitter {
|
|
|
84
84
|
(cb) => this.redisClient.halt(cb),
|
|
85
85
|
], cb);
|
|
86
86
|
}
|
|
87
|
-
static
|
|
87
|
+
static isExpiredHeartbeat(heartbeat) {
|
|
88
|
+
const { timestamp: heartbeatTimestamp } = heartbeat;
|
|
89
|
+
const timestamp = Date.now() - ConsumerHeartbeat.heartbeatTTL;
|
|
90
|
+
return heartbeatTimestamp > timestamp;
|
|
91
|
+
}
|
|
92
|
+
static getConsumersHeartbeats(redisClient, consumerIds, cb) {
|
|
88
93
|
const keyHeartbeats = redis_keys_1.redisKeys.getMainKeys().keyHeartbeats;
|
|
89
94
|
redisClient.hmget(keyHeartbeats, consumerIds, (err, reply) => {
|
|
90
95
|
if (err)
|
|
@@ -93,73 +98,25 @@ class ConsumerHeartbeat extends events_2.EventEmitter {
|
|
|
93
98
|
cb(new redis_smq_common_2.errors.InvalidCallbackReplyError());
|
|
94
99
|
else {
|
|
95
100
|
const r = {};
|
|
96
|
-
redis_smq_common_2.async.
|
|
97
|
-
const
|
|
98
|
-
const payload = reply[idx];
|
|
101
|
+
redis_smq_common_2.async.eachOf(consumerIds, (item, index, done) => {
|
|
102
|
+
const payload = reply[index];
|
|
99
103
|
if (payload) {
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
const consumerHeartbeat = JSON.parse(payload);
|
|
105
|
+
r[consumerIds[index]] = this.isExpiredHeartbeat(consumerHeartbeat)
|
|
106
|
+
? consumerHeartbeat
|
|
107
|
+
: false;
|
|
103
108
|
}
|
|
104
109
|
else
|
|
105
|
-
r[consumerIds[
|
|
110
|
+
r[consumerIds[index]] = false;
|
|
106
111
|
done();
|
|
107
112
|
}, () => cb(null, r));
|
|
108
113
|
}
|
|
109
114
|
});
|
|
110
115
|
}
|
|
111
|
-
static
|
|
112
|
-
ConsumerHeartbeat.getValidHeartbeatIds(redisClient, (err, consumerIds) => {
|
|
113
|
-
if (err)
|
|
114
|
-
cb(err);
|
|
115
|
-
else if (consumerIds && consumerIds.length) {
|
|
116
|
-
const { keyHeartbeats } = redis_keys_1.redisKeys.getMainKeys();
|
|
117
|
-
redisClient.hmget(keyHeartbeats, consumerIds, (err, res) => {
|
|
118
|
-
if (err)
|
|
119
|
-
cb(err);
|
|
120
|
-
else if (!res || res.length !== consumerIds.length)
|
|
121
|
-
cb(new redis_smq_common_2.errors.EmptyCallbackReplyError());
|
|
122
|
-
else {
|
|
123
|
-
const heartbeats = [];
|
|
124
|
-
redis_smq_common_2.async.each(res, (payload, index, done) => {
|
|
125
|
-
if (payload) {
|
|
126
|
-
const idx = Number(index);
|
|
127
|
-
const consumerId = consumerIds[idx];
|
|
128
|
-
heartbeats.push({
|
|
129
|
-
consumerId,
|
|
130
|
-
payload,
|
|
131
|
-
});
|
|
132
|
-
done();
|
|
133
|
-
}
|
|
134
|
-
else
|
|
135
|
-
done();
|
|
136
|
-
}, (err) => {
|
|
137
|
-
if (err)
|
|
138
|
-
cb(err);
|
|
139
|
-
else
|
|
140
|
-
cb(null, heartbeats);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
else
|
|
146
|
-
cb(null, []);
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
static getValidHeartbeatIds(redisClient, cb) {
|
|
116
|
+
static getExpiredHeartbeatIds(redisClient, offset, count, cb) {
|
|
150
117
|
const { keyHeartbeatConsumerWeight } = redis_keys_1.redisKeys.getMainKeys();
|
|
151
|
-
const
|
|
152
|
-
redisClient.zrangebyscore(keyHeartbeatConsumerWeight,
|
|
153
|
-
if (err)
|
|
154
|
-
cb(err);
|
|
155
|
-
else
|
|
156
|
-
cb(null, consumerIds !== null && consumerIds !== void 0 ? consumerIds : []);
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
static getExpiredHeartbeatIds(redisClient, cb) {
|
|
160
|
-
const { keyHeartbeatConsumerWeight } = redis_keys_1.redisKeys.getMainKeys();
|
|
161
|
-
const timestamp = Date.now() - ConsumerHeartbeat.heartbeatTTL;
|
|
162
|
-
redisClient.zrangebyscore(keyHeartbeatConsumerWeight, '-inf', timestamp, (err, consumerIds) => {
|
|
118
|
+
const ts = Date.now() - ConsumerHeartbeat.heartbeatTTL;
|
|
119
|
+
redisClient.zrangebyscore(keyHeartbeatConsumerWeight, '-inf', ts, offset, count, (err, consumerIds) => {
|
|
163
120
|
if (err)
|
|
164
121
|
cb(err);
|
|
165
122
|
else
|
|
@@ -15,15 +15,16 @@ exports.consumerQueues = {
|
|
|
15
15
|
if (err)
|
|
16
16
|
cb(err);
|
|
17
17
|
else {
|
|
18
|
+
const consumers = reply !== null && reply !== void 0 ? reply : {};
|
|
18
19
|
if (transform) {
|
|
19
20
|
const data = {};
|
|
20
|
-
redis_smq_common_1.async.
|
|
21
|
+
redis_smq_common_1.async.eachIn(consumers, (item, key, done) => {
|
|
21
22
|
data[key] = JSON.parse(item);
|
|
22
23
|
done();
|
|
23
24
|
}, () => cb(null, data));
|
|
24
25
|
}
|
|
25
26
|
else
|
|
26
|
-
cb(null,
|
|
27
|
+
cb(null, consumers);
|
|
27
28
|
}
|
|
28
29
|
});
|
|
29
30
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TConsumerMessageHandler, TConsumerRedisKeys, TConsumerInfo, TQueueParams, IConfig } from '../../../types';
|
|
1
|
+
import { TConsumerMessageHandler, TConsumerRedisKeys, TConsumerInfo, TQueueParams, IConfig, TConsumerHeartbeat } from '../../../types';
|
|
2
2
|
import { ConsumerHeartbeat } from './consumer-heartbeat';
|
|
3
3
|
import { Base } from '../base';
|
|
4
4
|
import { MessageHandlerRunner } from './consumer-message-handler/message-handler-runner';
|
|
@@ -23,11 +23,9 @@ export declare class Consumer extends Base {
|
|
|
23
23
|
cancel(queue: string | TQueueParams, cb: ICallback<void>): void;
|
|
24
24
|
getQueues(): TQueueParams[];
|
|
25
25
|
getRedisKeys(): TConsumerRedisKeys;
|
|
26
|
-
static
|
|
27
|
-
static
|
|
28
|
-
static
|
|
29
|
-
static
|
|
30
|
-
|
|
31
|
-
payload: string;
|
|
32
|
-
}[]>): void;
|
|
26
|
+
static getConsumersHeartbeats(redisClient: RedisClient, consumersIds: string[], cb: ICallback<Record<string, TConsumerHeartbeat | false>>): void;
|
|
27
|
+
static getConsumerHeartbeat(redisClient: RedisClient, consumerId: string, cb: ICallback<TConsumerHeartbeat | false>): void;
|
|
28
|
+
static getQueueConsumers(redisClient: RedisClient, queue: TQueueParams, transform: boolean | undefined, cb: ICallback<Record<string, TConsumerInfo | string>>): void;
|
|
29
|
+
static getQueueConsumerIds(redisClient: RedisClient, queue: TQueueParams, cb: ICallback<string[]>): void;
|
|
30
|
+
static countQueueConsumers(redisClient: RedisClient, queue: TQueueParams, cb: ICallback<number>): void;
|
|
33
31
|
}
|
|
@@ -116,18 +116,26 @@ class Consumer extends base_1.Base {
|
|
|
116
116
|
getRedisKeys() {
|
|
117
117
|
return this.redisKeys;
|
|
118
118
|
}
|
|
119
|
-
static
|
|
119
|
+
static getConsumersHeartbeats(redisClient, consumersIds, cb) {
|
|
120
|
+
consumer_heartbeat_1.ConsumerHeartbeat.getConsumersHeartbeats(redisClient, consumersIds, cb);
|
|
121
|
+
}
|
|
122
|
+
static getConsumerHeartbeat(redisClient, consumerId, cb) {
|
|
123
|
+
consumer_heartbeat_1.ConsumerHeartbeat.getConsumersHeartbeats(redisClient, [consumerId], (err, consumersHeartbeats = {}) => {
|
|
124
|
+
if (err)
|
|
125
|
+
cb(err);
|
|
126
|
+
else
|
|
127
|
+
cb(null, consumersHeartbeats[consumerId]);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
static getQueueConsumers(redisClient, queue, transform = false, cb) {
|
|
120
131
|
consumer_queues_1.consumerQueues.getQueueConsumers(redisClient, queue, transform, cb);
|
|
121
132
|
}
|
|
122
|
-
static
|
|
133
|
+
static getQueueConsumerIds(redisClient, queue, cb) {
|
|
123
134
|
consumer_queues_1.consumerQueues.getQueueConsumerIds(redisClient, queue, cb);
|
|
124
135
|
}
|
|
125
|
-
static
|
|
136
|
+
static countQueueConsumers(redisClient, queue, cb) {
|
|
126
137
|
consumer_queues_1.consumerQueues.countQueueConsumers(redisClient, queue, cb);
|
|
127
138
|
}
|
|
128
|
-
static getConsumerHeartbeats(redisClient, cb) {
|
|
129
|
-
consumer_heartbeat_1.ConsumerHeartbeat.getValidHeartbeats(redisClient, cb);
|
|
130
|
-
}
|
|
131
139
|
}
|
|
132
140
|
exports.Consumer = Consumer;
|
|
133
141
|
//# sourceMappingURL=consumer.js.map
|
|
@@ -11,7 +11,7 @@ const queue_not_found_error_1 = require("./errors/queue-not-found.error");
|
|
|
11
11
|
function validateMessageQueueDeletion(redisClient, queue, cb) {
|
|
12
12
|
const verifyHeartbeats = (consumerIds, cb) => {
|
|
13
13
|
if (consumerIds.length) {
|
|
14
|
-
consumer_heartbeat_1.ConsumerHeartbeat.
|
|
14
|
+
consumer_heartbeat_1.ConsumerHeartbeat.getConsumersHeartbeats(redisClient, consumerIds, (err, reply) => {
|
|
15
15
|
if (err)
|
|
16
16
|
cb(err);
|
|
17
17
|
else {
|
|
@@ -29,7 +29,7 @@ function validateMessageQueueDeletion(redisClient, queue, cb) {
|
|
|
29
29
|
cb();
|
|
30
30
|
};
|
|
31
31
|
const getOnlineConsumers = (cb) => {
|
|
32
|
-
consumer_1.Consumer.
|
|
32
|
+
consumer_1.Consumer.getQueueConsumerIds(redisClient, queue, cb);
|
|
33
33
|
};
|
|
34
34
|
redis_smq_common_1.async.waterfall([getOnlineConsumers, verifyHeartbeats], (err) => cb(err));
|
|
35
35
|
}
|
|
@@ -11,7 +11,7 @@ class ScheduleWorker extends redis_smq_common_1.Worker {
|
|
|
11
11
|
super(managed);
|
|
12
12
|
this.fetchMessageIds = (cb) => {
|
|
13
13
|
const { keyScheduledMessageWeight } = redis_keys_1.redisKeys.getMainKeys();
|
|
14
|
-
this.redisClient.zrangebyscore(keyScheduledMessageWeight, 0, Date.now(), cb);
|
|
14
|
+
this.redisClient.zrangebyscore(keyScheduledMessageWeight, 0, Date.now(), 0, 100, cb);
|
|
15
15
|
};
|
|
16
16
|
this.fetchMessages = (ids, cb) => {
|
|
17
17
|
if (ids.length) {
|
|
@@ -10,7 +10,7 @@ class WatchdogWorker extends redis_smq_common_1.Worker {
|
|
|
10
10
|
constructor(redisClient, config, managed, logger) {
|
|
11
11
|
super(managed);
|
|
12
12
|
this.work = (cb) => {
|
|
13
|
-
consumer_heartbeat_1.ConsumerHeartbeat.getExpiredHeartbeatIds(this.redisClient, (err, reply) => {
|
|
13
|
+
consumer_heartbeat_1.ConsumerHeartbeat.getExpiredHeartbeatIds(this.redisClient, 0, 100, (err, reply) => {
|
|
14
14
|
if (err)
|
|
15
15
|
cb(err);
|
|
16
16
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "redis-smq",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.3",
|
|
4
4
|
"description": "A simple high-performance Redis message queue for Node.js.",
|
|
5
5
|
"author": "Weyoss <weyoss@protonmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"uuid": "9.0.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"redis-smq-common": "^
|
|
42
|
+
"redis-smq-common": "^2.0.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/bluebird": "3.5.38",
|
|
@@ -51,7 +51,6 @@
|
|
|
51
51
|
"@types/uuid": "9.0.0",
|
|
52
52
|
"@typescript-eslint/eslint-plugin": "4.32.0",
|
|
53
53
|
"@typescript-eslint/parser": "4.32.0",
|
|
54
|
-
"coveralls": "3.1.1",
|
|
55
54
|
"eslint": "7.32.0",
|
|
56
55
|
"eslint-config-prettier": "8.3.0",
|
|
57
56
|
"eslint-plugin-prettier": "4.0.0",
|
|
@@ -59,7 +58,7 @@
|
|
|
59
58
|
"jest": "27.2.4",
|
|
60
59
|
"lint-staged": "11.1.2",
|
|
61
60
|
"prettier": "2.4.1",
|
|
62
|
-
"redis-smq-common": "^
|
|
61
|
+
"redis-smq-common": "^2.0.0",
|
|
63
62
|
"supertest": "6.1.6",
|
|
64
63
|
"ts-jest": "27.0.5",
|
|
65
64
|
"ts-node": "10.2.1",
|