@jetit/publisher 3.2.0 → 3.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": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "type": "commonjs",
5
5
  "dependencies": {
6
6
  "@jetit/id": "0.0.11",
@@ -10,6 +10,5 @@
10
10
  "peerDependencies": {
11
11
  "tslib": "2.5.3"
12
12
  },
13
- "main": "./src/index.js",
14
- "types": "./src/index.d.ts"
13
+ "main": "./src/index.js"
15
14
  }
@@ -1,4 +1,4 @@
1
- export { Streams as Publisher } from './redis/streams';
2
1
  export { setRedisConnectionSettings as setRedisConfig } from './redis/registry';
2
+ export { Streams as Publisher } from './redis/streams';
3
3
  export { ScheduledProcessor as __SCHEDULER_INTERNALS__ } from './redis/scheduler';
4
4
  export { UTILS as StreamUtilityFunctions } from './redis/utils';
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StreamUtilityFunctions = exports.__SCHEDULER_INTERNALS__ = exports.setRedisConfig = exports.Publisher = void 0;
4
- var streams_1 = require("./redis/streams");
5
- Object.defineProperty(exports, "Publisher", { enumerable: true, get: function () { return streams_1.Streams; } });
3
+ exports.StreamUtilityFunctions = exports.__SCHEDULER_INTERNALS__ = exports.Publisher = exports.setRedisConfig = void 0;
6
4
  var registry_1 = require("./redis/registry");
7
5
  Object.defineProperty(exports, "setRedisConfig", { enumerable: true, get: function () { return registry_1.setRedisConnectionSettings; } });
6
+ var streams_1 = require("./redis/streams");
7
+ Object.defineProperty(exports, "Publisher", { enumerable: true, get: function () { return streams_1.Streams; } });
8
8
  var scheduler_1 = require("./redis/scheduler");
9
9
  Object.defineProperty(exports, "__SCHEDULER_INTERNALS__", { enumerable: true, get: function () { return scheduler_1.ScheduledProcessor; } });
10
10
  var utils_1 = require("./redis/utils");
@@ -40,7 +40,7 @@ class ScheduledProcessor {
40
40
  const events = await this.redisPublisher.zrangebyscore('se', 0, currentTime);
41
41
  console.log('Events to process:', events.length);
42
42
  for (const eventString of events) {
43
- const eventData = JSON.parse(eventString);
43
+ const eventData = (0, utils_1.decodeScheduledMessage)(eventString);
44
44
  /**
45
45
  * Remove the event from the Redis Sorted Set first. Please note that
46
46
  * there is a chance of failure here if the process crashes before
@@ -1,5 +1,5 @@
1
- import { EventData, PublishData } from './types';
2
1
  import { Observable } from 'rxjs';
2
+ import { EventData, PublishData } from './types';
3
3
  export declare class Streams {
4
4
  private _redisPublisher?;
5
5
  private _redisGroups?;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Streams = void 0;
4
- const registry_1 = require("./registry");
5
- const rxjs_1 = require("rxjs");
6
4
  const id_1 = require("@jetit/id");
5
+ const rxjs_1 = require("rxjs");
6
+ const registry_1 = require("./registry");
7
7
  const utils_1 = require("./utils");
8
8
  function publisherErrorHandler(error) {
9
9
  console.error('PUBLISHER UNHANDLED ERROR: ', JSON.stringify(error));
@@ -98,20 +98,10 @@ class Streams {
98
98
  }
99
99
  else {
100
100
  if (uniquePerInstance === true) {
101
- const existingJob = await this.redisPublisher.zscore('se', JSON.stringify(eventData));
101
+ const existingJob = await this.redisPublisher.zscore('se', (0, utils_1.encodeScheduledMessage)(eventData));
102
102
  if (existingJob) {
103
- const parsedExistingJob = JSON.parse(existingJob);
104
- if (
105
- /** Repeating Jobs */
106
- (parsedExistingJob.eventName === eventData.eventName &&
107
- parsedExistingJob.repeatInterval &&
108
- (!parsedExistingJob.data || JSON.stringify(parsedExistingJob.data) === JSON.stringify(eventData.data))) ||
109
- /** Non-repeating schedules */
110
- (parsedExistingJob.eventName === eventData.eventName &&
111
- JSON.stringify(parsedExistingJob.data) === JSON.stringify(eventData.data))) {
112
- console.log(`PUBLISHER: Job with data '${eventData}' already exists. Skipping.`);
113
- return;
114
- }
103
+ console.log(`PUBLISHER: Job with data '${eventData}' already exists. Skipping.`);
104
+ return;
115
105
  }
116
106
  }
117
107
  await this.redisPublisher.zadd('se', scheduledTime.getTime(), JSON.stringify(eventData));
@@ -184,10 +174,17 @@ class Streams {
184
174
  const processMessage = async (redisClient, messageId, processPending = false) => {
185
175
  console.log(`PUBLISHER: Processing message ${messageId} for ${streamName}`);
186
176
  try {
187
- const pendingDetails = await redisClient.xpending(streamName, this.consumerGroupName, messageId, messageId, this.instanceId);
188
- if (pendingDetails[2] === 0) {
189
- console.warn(`PUBLISHER: Message ${messageId} for ${streamName} already acknowledged.`);
190
- return;
177
+ try {
178
+ const pendingDetails = await redisClient.xpending(streamName, this.consumerGroupName, messageId, messageId, 1, this.instanceId);
179
+ if (pendingDetails[2] === 0) {
180
+ console.warn(`PUBLISHER: Message ${messageId} for ${streamName} already acknowledged.`);
181
+ return;
182
+ }
183
+ }
184
+ catch (e) {
185
+ // Ignore the xpending error and continue
186
+ console.error('XPENDING ERROR: To be handled');
187
+ console.warn(JSON.stringify(e));
191
188
  }
192
189
  const messages = await redisClient.xrange(streamName, messageId, messageId);
193
190
  if (messages && messages.length) {
@@ -1,4 +1,5 @@
1
1
  import { RedisType } from './registry';
2
+ import { EventData } from './types';
2
3
  export declare function getAllConsumerGroups(eventName: string, redisConnection: RedisType): Promise<string[]>;
3
4
  export declare function getUnacknowledgedMessages(redisClient: RedisType, consumerGroupName: string, streamName: string, count?: number): Promise<{
4
5
  count: number;
@@ -11,6 +12,8 @@ export declare function getMessageStatesCount(redisClient: RedisType, streamName
11
12
  }>;
12
13
  export declare function notifySubscribers(redisClient: RedisType, eventName: string, messageId: string): Promise<void>;
13
14
  export declare function removedScheduledJob(redisClient: RedisType, eventString: string): Promise<void>;
15
+ export declare function encodeScheduledMessage<TData, TName extends string>(data: EventData<TData, TName>): string;
16
+ export declare function decodeScheduledMessage(data: string): EventData<never, never>;
14
17
  export declare const UTILS: {
15
18
  getMessageStatesCount: typeof getMessageStatesCount;
16
19
  getUnacknowledgedMessages: typeof getUnacknowledgedMessages;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UTILS = exports.removedScheduledJob = exports.notifySubscribers = exports.getMessageStatesCount = exports.getUnacknowledgedMessages = exports.getAllConsumerGroups = void 0;
3
+ exports.UTILS = exports.decodeScheduledMessage = exports.encodeScheduledMessage = exports.removedScheduledJob = exports.notifySubscribers = exports.getMessageStatesCount = exports.getUnacknowledgedMessages = exports.getAllConsumerGroups = void 0;
4
4
  async function getAllConsumerGroups(eventName, redisConnection) {
5
5
  const consumerGroups = await redisConnection.smembers(`${eventName}`);
6
6
  return consumerGroups;
@@ -58,6 +58,24 @@ async function removedScheduledJob(redisClient, eventString) {
58
58
  console.log(`Total Events in scheduled queue: ${eventsLater.length}`);
59
59
  }
60
60
  exports.removedScheduledJob = removedScheduledJob;
61
+ function encodeScheduledMessage(data) {
62
+ const eventName = data.eventName;
63
+ const eventData = JSON.stringify(data.data);
64
+ const repeatInterval = data.repeatInterval;
65
+ const eventDataBuffer = Buffer.from(eventData, 'utf8').toString('base64');
66
+ return `${eventName}%%${eventDataBuffer}%%${repeatInterval}`;
67
+ }
68
+ exports.encodeScheduledMessage = encodeScheduledMessage;
69
+ function decodeScheduledMessage(data) {
70
+ const parts = data.split('%%');
71
+ const eventName = parts[0];
72
+ return {
73
+ data: JSON.parse(Buffer.from(parts[1], 'base64').toString('utf-8')),
74
+ eventName,
75
+ repeatInterval: parts[2],
76
+ };
77
+ }
78
+ exports.decodeScheduledMessage = decodeScheduledMessage;
61
79
  exports.UTILS = {
62
80
  getMessageStatesCount,
63
81
  getUnacknowledgedMessages,