@jetit/publisher 1.7.2 → 2.0.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.7.2",
3
+ "version": "2.0.0",
4
4
  "type": "commonjs",
5
5
  "dependencies": {
6
6
  "@jetit/id": "0.0.11",
@@ -4,7 +4,7 @@ export type RedisType = Redis | Cluster;
4
4
  export declare class RedisRegistry {
5
5
  private static registry;
6
6
  private static options;
7
- static attemptConnection(connectionKey: string, storeRef?: number): Redis;
7
+ static attemptConnection(connectionKey: string, storeRef?: number): RedisType;
8
8
  static getConnection(connectionType?: string, storeRef?: number): RedisType;
9
9
  static setOptions(options: IOptions): void;
10
10
  static _getOptions(): IOptions;
@@ -7,11 +7,10 @@ class RedisRegistry {
7
7
  static attemptConnection(connectionKey, storeRef = 0) {
8
8
  let ref;
9
9
  if (RedisRegistry.options.cluster) {
10
- ref = new ioredis_1.Cluster(RedisRegistry.options.cluster.nodes, Object.assign(Object.assign({}, RedisRegistry.options.cluster.options), { redisOptions: {
11
- db: storeRef,
12
- } }));
10
+ ref = new ioredis_1.Cluster(RedisRegistry.options.cluster.nodes, Object.assign(Object.assign({}, RedisRegistry.options.cluster.options), { redisOptions: Object.assign(Object.assign({}, RedisRegistry.options.cluster.options.redisOptions), { db: storeRef }) }));
13
11
  }
14
- ref = new ioredis_1.default(Object.assign(Object.assign({}, RedisRegistry.options.redis), { db: storeRef }));
12
+ else
13
+ ref = new ioredis_1.default(Object.assign(Object.assign({}, RedisRegistry.options.redis), { db: storeRef }));
15
14
  RedisRegistry.registry.set(connectionKey, ref);
16
15
  return ref;
17
16
  }
@@ -20,11 +19,10 @@ class RedisRegistry {
20
19
  let ref = this.registry.get(connectionKey);
21
20
  if (!ref) {
22
21
  if (RedisRegistry.options.cluster) {
23
- ref = new ioredis_1.Cluster(RedisRegistry.options.cluster.nodes, Object.assign(Object.assign({}, RedisRegistry.options.cluster.options), { redisOptions: {
24
- db: storeRef,
25
- } }));
22
+ ref = new ioredis_1.Cluster(RedisRegistry.options.cluster.nodes, Object.assign(Object.assign({}, RedisRegistry.options.cluster.options), { redisOptions: Object.assign(Object.assign({}, RedisRegistry.options.cluster.options.redisOptions), { db: storeRef }) }));
26
23
  }
27
- ref = new ioredis_1.default(Object.assign(Object.assign({}, RedisRegistry.options.redis), { db: storeRef }));
24
+ else
25
+ ref = new ioredis_1.default(Object.assign(Object.assign({}, RedisRegistry.options.redis), { db: storeRef }));
28
26
  }
29
27
  return ref;
30
28
  }
@@ -51,23 +51,21 @@ 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({ pipeline: true });
55
54
  eventData.eventId = (0, id_1.generateID)('HEX', 'FF');
56
- transaction.zrem('se', eventString);
55
+ yield this.redisPublisher.zrem('se', eventString);
57
56
  const consumerGroups = yield (0, groups_1.getAllConsumerGroups)(eventData.eventName, this.redisPublisher);
58
57
  console.log('Scheduled Publishing to consumer groups: ', consumerGroups, 'with id ', eventData.eventId, '...');
59
58
  for (const consumerGroup of consumerGroups) {
60
59
  // Publish the event to each consumer group's stream
61
60
  const streamName = `${eventData.eventName}:${consumerGroup}`;
62
- transaction.xadd(streamName, '*', 'data', JSON.stringify(eventData));
61
+ yield this.redisPublisher.xadd(streamName, '*', 'data', JSON.stringify(eventData));
63
62
  }
64
63
  if (eventData.repeatInterval) {
65
64
  const nextEventTime = currentTime + eventData.repeatInterval;
66
65
  const nextEventString = JSON.stringify(Object.assign({}, eventData));
67
- transaction.zadd('se', nextEventTime, nextEventString);
66
+ yield this.redisPublisher.zadd('se', nextEventTime, nextEventString);
68
67
  }
69
- transaction.publish(eventData.eventName, '');
70
- yield transaction.exec();
68
+ yield this.redisPublisher.publish(eventData.eventName, '');
71
69
  }
72
70
  });
73
71
  }
@@ -82,16 +82,14 @@ class Streams {
82
82
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
83
83
  const processedMessagesKeyPattern = `pm:${this.consumerGroupName}:*`;
84
84
  let cursor = '0';
85
- const transaction = this.redisGroups.pipeline();
86
85
  do {
87
86
  const [nextCursor, keys] = yield this.redisGroups.scan(cursor, 'MATCH', processedMessagesKeyPattern);
88
87
  cursor = nextCursor;
89
88
  for (const key of keys) {
90
89
  const oneHourAgo = Date.now() - 60 * 60 * 1000;
91
- transaction.zremrangebyscore(key, '-inf', oneHourAgo);
90
+ yield this.redisGroups.zremrangebyscore(key, '-inf', oneHourAgo);
92
91
  }
93
92
  } while (cursor !== '0');
94
- yield transaction.exec();
95
93
  });
96
94
  }
97
95
  publish(data) {
@@ -101,20 +99,21 @@ class Streams {
101
99
  data.eventId = (0, id_1.generateID)('HEX', 'FF');
102
100
  if (!data.createdAt)
103
101
  data.createdAt = Date.now();
104
- const transaction = this.redisPublisher.multi({ pipeline: true });
105
102
  const consumerGroups = yield (0, groups_1.getAllConsumerGroups)(data.eventName, this.redisPublisher);
106
103
  if (consumerGroups.length > 0) {
107
104
  console.log(`PUBLISHER: Publishing event ${data.eventName} to consumer groups: ${consumerGroups.join(', ')}`);
108
- for (const consumerGroup of consumerGroups) {
109
- // Publish the event to each consumer group's stream
110
- const streamName = `${data.eventName}:${consumerGroup}`;
111
- transaction.xadd(streamName, '*', 'data', JSON.stringify(data));
105
+ try {
106
+ for (const consumerGroup of consumerGroups) {
107
+ // Publish the event to each consumer group's stream
108
+ const streamName = `${data.eventName}:${consumerGroup}`;
109
+ yield this.redisPublisher.xadd(streamName, '*', 'data', JSON.stringify(data));
110
+ }
111
+ yield this.redisPublisher.publish(data.eventName, '');
112
112
  }
113
- transaction.publish(data.eventName, '');
114
- yield transaction.exec().catch((error) => {
113
+ catch (error) {
115
114
  console.error(`PUBLISHER: Error while publishing event for service ${this.consumerGroupName} with instance ${this.instanceId}: `, error);
116
115
  throw new Error('Publisher Error');
117
- });
116
+ }
118
117
  }
119
118
  else
120
119
  console.log(`PUBLISHER: Event publish failed for event ${data.eventName}, reason: no consumers ${consumerGroups}`);
@@ -187,19 +186,24 @@ class Streams {
187
186
  }
188
187
  createConsumerAndRegister(eventName) {
189
188
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
190
- const pipeline = this.redisGroups.multi();
191
189
  const streamName = `${eventName}:${this.consumerGroupName}`;
192
190
  const key = `instance:${this.instanceId}:subscribedEvents`;
193
191
  const setKeyForK8sHandling = `instance:${this.instanceUniqueId}:consumerGroupName`;
194
192
  this.eventsListened.push(eventName);
195
- pipeline.xgroup('CREATE', streamName, this.consumerGroupName, '0', 'MKSTREAM');
196
- pipeline.xgroup('CREATECONSUMER', streamName, this.consumerGroupName, this.instanceId);
197
- pipeline.sadd(key, eventName);
198
- pipeline.sadd(`${eventName}`, this.consumerGroupName);
199
- pipeline.set(setKeyForK8sHandling, this.consumerGroupName);
200
- const [, createConsumerStatus, addToCGSet, addToFlushSet] = (yield pipeline.exec());
201
- console.log(`PUBLISHER: Consumer Registered and created with ${this.instanceId} under ${this.consumerGroupName} with ${createConsumerStatus[1]} consumers and with the following status ${JSON.stringify({ addToCGSet, addToFlushSet })}`);
202
- return createConsumerStatus[1] === 0 || createConsumerStatus[1] === 1;
193
+ yield this.redisGroups
194
+ .xgroup('CREATE', streamName, this.consumerGroupName, '0', 'MKSTREAM')
195
+ .then((v) => {
196
+ console.log(`Group created created for ${JSON.stringify({ streamName, cgn: this.consumerGroupName })}`);
197
+ })
198
+ .catch((e) => {
199
+ console.log(`Group creation failed with error ${e.message} for ${JSON.stringify({ streamName, cgn: this.consumerGroupName })}`);
200
+ });
201
+ const createConsumerStatus = (yield this.redisGroups.xgroup('CREATECONSUMER', streamName, this.consumerGroupName, this.instanceId));
202
+ yield this.redisGroups.sadd(key, eventName);
203
+ const addToCGSet = yield this.redisGroups.sadd(`${eventName}`, this.consumerGroupName);
204
+ const addToFlushSet = yield this.redisGroups.set(setKeyForK8sHandling, this.consumerGroupName);
205
+ console.log(`PUBLISHER: Consumer Registered and created with ${this.instanceId} under ${this.consumerGroupName} with ${createConsumerStatus} consumers and with the following status ${JSON.stringify({ addToCGSet, addToFlushSet })}`);
206
+ return createConsumerStatus === 0 || createConsumerStatus === 1;
203
207
  });
204
208
  }
205
209
  listenInternals(eventName) {
@@ -237,11 +241,9 @@ class Streams {
237
241
  bs.next(eventData);
238
242
  const pmKey = `pm:${this.consumerGroupName}:${streamName}`;
239
243
  const currentTime = Date.now();
240
- const transaction = redisClient.multi({ pipeline: true });
241
- transaction.zadd(pmKey, currentTime, messageId);
242
- transaction.xack(streamName, this.consumerGroupName, id);
243
- transaction.zadd(`ack:${streamName}`, Date.now(), id);
244
- yield transaction.exec();
244
+ yield redisClient.zadd(pmKey, currentTime, messageId);
245
+ yield redisClient.xack(streamName, this.consumerGroupName, id);
246
+ yield redisClient.zadd(`ack:${streamName}`, Date.now(), id);
245
247
  }
246
248
  }
247
249
  this.scanAndClaimAUnclaimedMessage(streamName)
@@ -333,14 +335,12 @@ class Streams {
333
335
  const cleanupThreshold = Date.now() - interval;
334
336
  const acknowledgedMessages = yield this.redisGroups.zrangebyscore(`ack:${streamName}`, '-inf', cleanupThreshold);
335
337
  if (acknowledgedMessages && acknowledgedMessages.length > 0) {
336
- const transaction = this.redisGroups.pipeline();
337
338
  // Remove acknowledged messages from the stream
338
339
  for (const messageId of acknowledgedMessages) {
339
- transaction.xdel(streamName, messageId);
340
+ yield this.redisGroups.xdel(streamName, messageId);
340
341
  }
341
342
  // Remove acknowledged messages from the Sorted Set
342
- transaction.zremrangebyscore(`ack:${streamName}`, '-inf', cleanupThreshold);
343
- yield transaction.exec();
343
+ yield this.redisGroups.zremrangebyscore(`ack:${streamName}`, '-inf', cleanupThreshold);
344
344
  }
345
345
  });
346
346
  }