@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jetit/publisher",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "type": "commonjs",
5
5
  "dependencies": {
6
6
  "@jetit/id": "0.0.11",
@@ -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);
@@ -149,5 +149,6 @@ export declare class Streams {
149
149
  close(): Promise<void>;
150
150
  private clearSubscribedEvents;
151
151
  private registerConsumerGroup;
152
+ releaseAllClaims(eventName: string): Promise<void>;
152
153
  private cleanupAcknowledgedMessages;
153
154
  }
@@ -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.multi();
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);