@jetit/publisher 1.1.1 → 1.1.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/package.json
CHANGED
|
@@ -51,7 +51,7 @@ class ScheduledProcessor {
|
|
|
51
51
|
* Instead of using the publish method directly, the entire logic is
|
|
52
52
|
* copy pasted to reduce the case of failure.
|
|
53
53
|
*/
|
|
54
|
-
const transaction = this.redisPublisher.multi();
|
|
54
|
+
const transaction = this.redisPublisher.multi({ pipeline: true });
|
|
55
55
|
eventData.eventId = (0, id_1.generateID)('HEX', 'FF');
|
|
56
56
|
transaction.zrem('se', eventString);
|
|
57
57
|
const consumerGroups = yield (0, groups_1.getAllConsumerGroups)(eventData.eventName, this.redisPublisher);
|
package/src/lib/redis/streams.js
CHANGED
|
@@ -110,7 +110,7 @@ class Streams {
|
|
|
110
110
|
data.eventId = (0, id_1.generateID)('HEX', 'FF');
|
|
111
111
|
if (!data.createdAt)
|
|
112
112
|
data.createdAt = Date.now();
|
|
113
|
-
const transaction = this.redisPublisher.multi();
|
|
113
|
+
const transaction = this.redisPublisher.multi({ pipeline: true });
|
|
114
114
|
const consumerGroups = yield (0, groups_1.getAllConsumerGroups)(data.eventName, this.redisPublisher);
|
|
115
115
|
if (consumerGroups.length > 0) {
|
|
116
116
|
console.log(`Publishing event ${data.eventName} to consumer groups: ${consumerGroups.join(', ')}`);
|
|
@@ -236,7 +236,7 @@ class Streams {
|
|
|
236
236
|
bs.next(eventData);
|
|
237
237
|
const pmKey = `pm:${this.consumerGroupName}:${streamName}`;
|
|
238
238
|
const currentTime = Date.now();
|
|
239
|
-
const transaction = this.redisGroups.multi();
|
|
239
|
+
const transaction = this.redisGroups.multi({ pipeline: true });
|
|
240
240
|
transaction.zadd(pmKey, currentTime, messageId);
|
|
241
241
|
transaction.xack(streamName, this.consumerGroupName, id);
|
|
242
242
|
transaction.zadd(`ack:${streamName}`, Date.now(), id);
|
|
@@ -275,17 +275,19 @@ class Streams {
|
|
|
275
275
|
const result = yield this.redisGroups.xreadgroup('GROUP', this.consumerGroupName, this.instanceId, 'STREAMS', streamName, '>');
|
|
276
276
|
if (result) {
|
|
277
277
|
const [, streamMessages] = result[0];
|
|
278
|
+
if (!streamMessages)
|
|
279
|
+
return;
|
|
278
280
|
console.log(`Unprocessed events: ${streamMessages.length}`);
|
|
279
|
-
const transaction = this.redisGroups.multi();
|
|
280
281
|
for (const [id, data] of streamMessages) {
|
|
281
282
|
const eventData = JSON.parse(data[1]);
|
|
283
|
+
const transaction = this.redisGroups.multi();
|
|
282
284
|
// Republishing the events
|
|
283
285
|
transaction.xadd(streamName, '*', 'data', JSON.stringify(eventData));
|
|
284
286
|
transaction.publish(eventName, '');
|
|
285
287
|
transaction.xack(streamName, this.consumerGroupName, id);
|
|
288
|
+
yield transaction.exec().catch(publisherErrorHandler);
|
|
286
289
|
console.log(`Event ${eventName} with ID: ${id} published`);
|
|
287
290
|
}
|
|
288
|
-
yield transaction.exec();
|
|
289
291
|
}
|
|
290
292
|
});
|
|
291
293
|
}
|
|
@@ -312,7 +314,6 @@ class Streams {
|
|
|
312
314
|
const [, minId, maxId, consumers] = pendingMessages;
|
|
313
315
|
if (!consumers || consumers.length === 0)
|
|
314
316
|
return;
|
|
315
|
-
const transaction = this.redisGroups.multi();
|
|
316
317
|
for (const [consumer, pendingCount] of consumers) {
|
|
317
318
|
if (parseInt(pendingCount) > 0) {
|
|
318
319
|
const pending = (yield this.redisGroups.xpending(streamName, this.consumerGroupName, minId, maxId, Number(pendingCount), consumer));
|
|
@@ -321,14 +322,15 @@ class Streams {
|
|
|
321
322
|
if (claimedMessage) {
|
|
322
323
|
const [, data] = claimedMessage[0];
|
|
323
324
|
const eventData = JSON.parse(data[1]);
|
|
325
|
+
const transaction = this.redisGroups.multi();
|
|
324
326
|
transaction.xadd(streamName, '*', 'data', JSON.stringify(eventData));
|
|
325
327
|
transaction.publish(eventName, '');
|
|
326
328
|
transaction.xack(streamName, this.consumerGroupName, messageId);
|
|
329
|
+
yield transaction.exec().catch(publisherErrorHandler);
|
|
327
330
|
}
|
|
328
331
|
}
|
|
329
332
|
}
|
|
330
333
|
}
|
|
331
|
-
yield transaction.exec();
|
|
332
334
|
});
|
|
333
335
|
}
|
|
334
336
|
/**
|
|
@@ -373,6 +375,9 @@ class Streams {
|
|
|
373
375
|
console.log(`${this.eventsListened.length} events to be cleared`);
|
|
374
376
|
for (const eventName of this.eventsListened) {
|
|
375
377
|
yield this.redisGroups.srem(`${eventName}`, this.consumerGroupName);
|
|
378
|
+
// Releasing all claims based on info from: https://redis.io/commands/xgroup-delconsumer/
|
|
379
|
+
yield this.releaseAllClaims(eventName);
|
|
380
|
+
yield this.redisGroups.xgroup('DELCONSUMER', eventName, this.consumerGroupName, this.instanceId);
|
|
376
381
|
}
|
|
377
382
|
});
|
|
378
383
|
}
|
|
@@ -381,13 +386,28 @@ class Streams {
|
|
|
381
386
|
yield this.redisGroups.sadd(`${eventName}`, this.consumerGroupName);
|
|
382
387
|
});
|
|
383
388
|
}
|
|
389
|
+
releaseAllClaims(eventName) {
|
|
390
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
391
|
+
// Retrieve the pending messages for the consumer
|
|
392
|
+
const pendingMessages = (yield this.redisGroups.xpending(eventName, this.consumerGroupName, '-', '+', 1000, this.instanceId));
|
|
393
|
+
if (pendingMessages && pendingMessages.length > 0) {
|
|
394
|
+
const transaction = this.redisGroups.multi({ pipeline: true });
|
|
395
|
+
for (const [messageId] of pendingMessages) {
|
|
396
|
+
// Setting the idle time to 10000 ms to make sure this consumer shuts down completely
|
|
397
|
+
const idleTime = 10000;
|
|
398
|
+
transaction.xclaim(eventName, this.consumerGroupName, this.instanceId, idleTime);
|
|
399
|
+
}
|
|
400
|
+
yield transaction.exec();
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
}
|
|
384
404
|
cleanupAcknowledgedMessages(eventName, interval = 60 * 60 * 1000) {
|
|
385
405
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
386
406
|
const streamName = `${eventName}:${this.consumerGroupName}`;
|
|
387
407
|
const cleanupThreshold = Date.now() - interval;
|
|
388
408
|
const acknowledgedMessages = yield this.redisGroups.zrangebyscore(`ack:${streamName}`, '-inf', cleanupThreshold);
|
|
389
409
|
if (acknowledgedMessages && acknowledgedMessages.length > 0) {
|
|
390
|
-
const transaction = this.redisGroups.
|
|
410
|
+
const transaction = this.redisGroups.pipeline();
|
|
391
411
|
// Remove acknowledged messages from the stream
|
|
392
412
|
for (const messageId of acknowledgedMessages) {
|
|
393
413
|
transaction.xdel(streamName, messageId);
|