@jetit/publisher 1.1.3 → 1.3.0

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.3",
3
+ "version": "1.3.0",
4
4
  "type": "commonjs",
5
5
  "dependencies": {
6
6
  "@jetit/id": "0.0.11",
@@ -43,16 +43,17 @@ class Streams {
43
43
  var _a;
44
44
  this.eventsListened = [];
45
45
  this.instanceId = `${serviceName}:${(0, id_1.generateID)('HEX', 'FE')}`;
46
+ console.log(this.instanceId);
46
47
  this.consumerGroupName = `cg-${serviceName}`;
47
48
  const cleanUpInterval = (_a = parseInt(process.env['CLEANUP_INTERVAL'] || `${1000 * 60 * 60}`, 10)) !== null && _a !== void 0 ? _a : 1000 * 60 * 60;
48
- setTimeout(() => this.runClear(cleanUpInterval), 3000);
49
+ setTimeout(() => this.runClear(cleanUpInterval), 60000);
49
50
  this.cleanUpTimer = setInterval(() => {
50
51
  this.runClear(cleanUpInterval);
51
52
  }, cleanUpInterval);
52
53
  }
53
54
  runClear(cleanUpInterval) {
54
55
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
55
- console.log('Running Publisher Clearance');
56
+ console.log('Running Publisher Clearance', this.eventsListened);
56
57
  this.clearDuplicationCheckKeys();
57
58
  for (const eventName of this.eventsListened) {
58
59
  process.nextTick(() => tslib_1.__awaiter(this, void 0, void 0, function* () {
@@ -271,23 +272,25 @@ class Streams {
271
272
  */
272
273
  republishUnprocessedEvents(eventName) {
273
274
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
275
+ console.log('Republishing Unprocessed Events.');
274
276
  const streamName = `${eventName}:${this.consumerGroupName}`;
275
277
  const result = yield this.redisGroups.xreadgroup('GROUP', this.consumerGroupName, this.instanceId, 'STREAMS', streamName, '>');
276
- if (result) {
277
- const [, streamMessages] = result[0];
278
- if (!streamMessages)
279
- return;
280
- console.log(`Unprocessed events: ${streamMessages.length}`);
281
- for (const [id, data] of streamMessages) {
282
- const eventData = JSON.parse(data[1]);
283
- const transaction = this.redisGroups.multi();
284
- // Republishing the events
285
- transaction.xadd(streamName, '*', 'data', JSON.stringify(eventData));
286
- transaction.publish(eventName, '');
287
- transaction.xack(streamName, this.consumerGroupName, id);
288
- yield transaction.exec().catch(publisherErrorHandler);
289
- console.log(`Event ${eventName} with ID: ${id} published`);
290
- }
278
+ if (!result)
279
+ return;
280
+ const [, streamMessages] = result[0];
281
+ if (!streamMessages)
282
+ return;
283
+ console.log(`Unprocessed events: ${streamMessages.length}`);
284
+ for (const [id, data] of streamMessages) {
285
+ const transaction = this.redisGroups.multi({ pipeline: true });
286
+ const eventData = JSON.parse(data[1]);
287
+ // Republishing the events
288
+ transaction.xadd(streamName, '*', 'data', JSON.stringify(eventData));
289
+ transaction.publish(eventName, '');
290
+ transaction.xack(streamName, this.consumerGroupName, id);
291
+ yield transaction.exec().catch(publisherErrorHandler);
292
+ console.log(`Event ${eventName} with ID: ${id} published`);
293
+ yield transaction.exec();
291
294
  }
292
295
  });
293
296
  }
@@ -307,6 +310,7 @@ class Streams {
307
310
  */
308
311
  recoverCrashedConsumerMessages(eventName, idleTimeout = 30000) {
309
312
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
313
+ console.log(`PUBLISHER: Running recoverCrashedConsumerMessages`);
310
314
  const streamName = `${eventName}:${this.consumerGroupName}`;
311
315
  const pendingMessages = (yield this.redisGroups.xpending(streamName, this.consumerGroupName));
312
316
  if (!pendingMessages)
@@ -315,19 +319,22 @@ class Streams {
315
319
  if (!consumers || consumers.length === 0)
316
320
  return;
317
321
  for (const [consumer, pendingCount] of consumers) {
318
- if (parseInt(pendingCount) > 0) {
319
- const pending = (yield this.redisGroups.xpending(streamName, this.consumerGroupName, minId, maxId, Number(pendingCount), consumer));
320
- for (const [messageId] of pending) {
321
- const claimedMessage = (yield this.redisGroups.xclaim(streamName, this.consumerGroupName, this.instanceId, idleTimeout, messageId));
322
- if (claimedMessage) {
323
- const [, data] = claimedMessage[0];
324
- const eventData = JSON.parse(data[1]);
325
- const transaction = this.redisGroups.multi();
326
- transaction.xadd(streamName, '*', 'data', JSON.stringify(eventData));
327
- transaction.publish(eventName, '');
328
- transaction.xack(streamName, this.consumerGroupName, messageId);
329
- yield transaction.exec().catch(publisherErrorHandler);
330
- }
322
+ if (parseInt(pendingCount) < 0)
323
+ return;
324
+ const pending = (yield this.redisGroups.xpending(streamName, this.consumerGroupName, minId, maxId, Number(pendingCount), consumer));
325
+ if (!pending)
326
+ return;
327
+ for (const [messageId] of pending) {
328
+ const claimedMessage = (yield this.redisGroups.xclaim(streamName, this.consumerGroupName, this.instanceId, idleTimeout, messageId));
329
+ if (claimedMessage) {
330
+ console.log({ claimedMessage: JSON.stringify(claimedMessage) });
331
+ const [, data] = claimedMessage[0];
332
+ const eventData = JSON.parse(data[1]);
333
+ const transaction = this.redisGroups.multi();
334
+ transaction.xadd(streamName, '*', 'data', JSON.stringify(eventData));
335
+ transaction.publish(eventName, '');
336
+ transaction.xack(streamName, this.consumerGroupName, messageId);
337
+ yield transaction.exec().catch(publisherErrorHandler);
331
338
  }
332
339
  }
333
340
  }
@@ -355,7 +362,7 @@ class Streams {
355
362
  */
356
363
  close() {
357
364
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
358
- this.clearSubscribedEvents();
365
+ yield this.clearSubscribedEvents();
359
366
  if (this.redisPublisher) {
360
367
  yield this.redisPublisher.quit();
361
368
  }
@@ -373,11 +380,17 @@ class Streams {
373
380
  clearSubscribedEvents() {
374
381
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
375
382
  console.log(`${this.eventsListened.length} events to be cleared`);
383
+ let x = this.eventsListened.length;
376
384
  for (const eventName of this.eventsListened) {
385
+ console.log(`${eventName} is being cleared in publisher`);
377
386
  yield this.redisGroups.srem(`${eventName}`, this.consumerGroupName);
387
+ console.log(`${eventName} is removed from ${this.consumerGroupName}`);
378
388
  // Releasing all claims based on info from: https://redis.io/commands/xgroup-delconsumer/
379
389
  yield this.releaseAllClaims(eventName);
390
+ console.log(`${eventName} removes all claims`);
380
391
  yield this.redisGroups.xgroup('DELCONSUMER', eventName, this.consumerGroupName, this.instanceId);
392
+ console.log(`${eventName} is deleted as a consumer from ${this.consumerGroupName}, ${this.instanceId}`);
393
+ console.log(x--);
381
394
  }
382
395
  });
383
396
  }
@@ -388,14 +401,18 @@ class Streams {
388
401
  }
389
402
  releaseAllClaims(eventName) {
390
403
  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));
404
+ /**
405
+ * Retrieve the pending messages for the consumer. Note this only fetches the last
406
+ * 10000 events assigned to this consumer. This function has been modified to make sure
407
+ * that there is a temp instance that claims all this messages
408
+ */
409
+ const pendingMessages = (yield this.redisGroups.xpending(eventName, this.consumerGroupName, '-', '+', 10000, this.instanceId));
393
410
  if (pendingMessages && pendingMessages.length > 0) {
411
+ console.log(`${pendingMessages.length} messages to clean up.`);
394
412
  const transaction = this.redisGroups.multi({ pipeline: true });
413
+ const tempConsumerId = `${this.instanceId}-temp`;
395
414
  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);
415
+ transaction.xclaim(eventName, this.consumerGroupName, tempConsumerId, 10, messageId);
399
416
  }
400
417
  yield transaction.exec();
401
418
  }