@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.
|
|
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
|
}
|
package/src/lib/publisher.d.ts
CHANGED
|
@@ -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';
|
package/src/lib/publisher.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.StreamUtilityFunctions = exports.__SCHEDULER_INTERNALS__ = exports.
|
|
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 =
|
|
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
|
package/src/lib/redis/streams.js
CHANGED
|
@@ -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',
|
|
101
|
+
const existingJob = await this.redisPublisher.zscore('se', (0, utils_1.encodeScheduledMessage)(eventData));
|
|
102
102
|
if (existingJob) {
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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) {
|
package/src/lib/redis/utils.d.ts
CHANGED
|
@@ -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;
|
package/src/lib/redis/utils.js
CHANGED
|
@@ -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,
|