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 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 validateHeartbeatsOf(redisClient: RedisClient, consumerIds: string[], cb: ICallback<Record<string, boolean>>): void;
19
- static getValidHeartbeats(redisClient: RedisClient, cb: ICallback<{
20
- consumerId: string;
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 validateHeartbeatsOf(redisClient, consumerIds, cb) {
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.each(consumerIds, (item, index, done) => {
97
- const idx = Number(index);
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 { timestamp: heartbeatTimestamp } = JSON.parse(payload);
101
- const timestamp = Date.now() - ConsumerHeartbeat.heartbeatTTL;
102
- r[consumerIds[idx]] = heartbeatTimestamp > timestamp;
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[idx]] = false;
110
+ r[consumerIds[index]] = false;
106
111
  done();
107
112
  }, () => cb(null, r));
108
113
  }
109
114
  });
110
115
  }
111
- static getValidHeartbeats(redisClient, cb) {
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 timestamp = Date.now() - ConsumerHeartbeat.heartbeatTTL;
152
- redisClient.zrangebyscore(keyHeartbeatConsumerWeight, timestamp, '+inf', (err, consumerIds) => {
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.each(reply !== null && reply !== void 0 ? reply : {}, (item, key, done) => {
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, reply !== null && reply !== void 0 ? reply : {});
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 getOnlineConsumers(redisClient: RedisClient, queue: TQueueParams, transform: boolean | undefined, cb: ICallback<Record<string, TConsumerInfo | string>>): void;
27
- static getOnlineConsumerIds(redisClient: RedisClient, queue: TQueueParams, cb: ICallback<string[]>): void;
28
- static countOnlineConsumers(redisClient: RedisClient, queue: TQueueParams, cb: ICallback<number>): void;
29
- static getConsumerHeartbeats(redisClient: RedisClient, cb: ICallback<{
30
- consumerId: string;
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 getOnlineConsumers(redisClient, queue, transform = false, cb) {
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 getOnlineConsumerIds(redisClient, queue, cb) {
133
+ static getQueueConsumerIds(redisClient, queue, cb) {
123
134
  consumer_queues_1.consumerQueues.getQueueConsumerIds(redisClient, queue, cb);
124
135
  }
125
- static countOnlineConsumers(redisClient, queue, cb) {
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.validateHeartbeatsOf(redisClient, consumerIds, (err, reply) => {
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.getOnlineConsumerIds(redisClient, queue, cb);
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.1",
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": "^1.0.6"
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": "^1.0.6",
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",