@cap-js-community/event-queue 1.9.0 → 1.9.1
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 +1 -1
- package/src/EventQueueProcessorBase.js +2 -1
- package/src/config.js +4 -0
- package/src/initialize.js +1 -1
- package/src/periodicEvents.js +8 -2
- package/src/processEventQueue.js +16 -4
- package/src/runner/runner.js +4 -1
- package/src/shared/common.js +0 -1
- package/src/shared/distributedLock.js +11 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cap-js-community/event-queue",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"description": "An event queue that enables secure transactional processing of asynchronous and periodic events, featuring instant event processing with Redis Pub/Sub and load distribution across all application instances.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -929,6 +929,7 @@ class EventQueueProcessorBase {
|
|
|
929
929
|
}
|
|
930
930
|
});
|
|
931
931
|
}
|
|
932
|
+
this.logger.info("keep alive finished!", { numberOfEvents: ids.length });
|
|
932
933
|
});
|
|
933
934
|
}).catch((err) => {
|
|
934
935
|
this.logger.error("keep alive handling failed!", err);
|
|
@@ -971,7 +972,7 @@ class EventQueueProcessorBase {
|
|
|
971
972
|
{ expiryTime: this.#eventConfig.keepAliveMaxInProgressTime }
|
|
972
973
|
);
|
|
973
974
|
if (!lockAcquired) {
|
|
974
|
-
this.logger.error("renewing
|
|
975
|
+
this.logger.error("renewing distributed lock failed!", {
|
|
975
976
|
type: this.#eventType,
|
|
976
977
|
subType: this.#eventSubType,
|
|
977
978
|
});
|
package/src/config.js
CHANGED
|
@@ -529,6 +529,10 @@ class Config {
|
|
|
529
529
|
this.#configEvents = JSON.parse(JSON.stringify(value));
|
|
530
530
|
}
|
|
531
531
|
|
|
532
|
+
get hasConfigEvents() {
|
|
533
|
+
return !!(Object.keys(this.#configEvents ?? {}).length || Object.keys(this.#configPeriodicEvents ?? {}).length);
|
|
534
|
+
}
|
|
535
|
+
|
|
532
536
|
set configPeriodicEvents(value) {
|
|
533
537
|
this.#configPeriodicEvents = JSON.parse(JSON.stringify(value));
|
|
534
538
|
}
|
package/src/initialize.js
CHANGED
|
@@ -134,7 +134,7 @@ const readConfigFromFile = async (configFilepath) => {
|
|
|
134
134
|
"configFilepath with unsupported extension, allowed extensions are .yaml and .json"
|
|
135
135
|
);
|
|
136
136
|
} catch (err) {
|
|
137
|
-
if (config.useAsCAPOutbox) {
|
|
137
|
+
if (!configFilepath && (config.useAsCAPOutbox || config.hasConfigEvents)) {
|
|
138
138
|
return {};
|
|
139
139
|
}
|
|
140
140
|
throw err;
|
package/src/periodicEvents.js
CHANGED
|
@@ -150,8 +150,14 @@ const _insertPeriodEvents = async (tx, events, now) => {
|
|
|
150
150
|
processChunkedSync(eventsToBeInserted, CHUNK_SIZE_INSERT_PERIODIC_EVENTS, (chunk) => {
|
|
151
151
|
logger.info(`${counter}/${chunks} | inserting chunk of changed or new periodic events`, {
|
|
152
152
|
events: chunk.map(({ type, subType, startAfter }) => {
|
|
153
|
-
const { interval } = eventConfig.getEventConfig(type, subType);
|
|
154
|
-
return {
|
|
153
|
+
const { interval, cron } = eventConfig.getEventConfig(type, subType);
|
|
154
|
+
return {
|
|
155
|
+
type,
|
|
156
|
+
subType,
|
|
157
|
+
...(startAfter && { startAfter }),
|
|
158
|
+
...(interval && { interval }),
|
|
159
|
+
...(cron && { cron }),
|
|
160
|
+
};
|
|
155
161
|
}),
|
|
156
162
|
});
|
|
157
163
|
counter++;
|
package/src/processEventQueue.js
CHANGED
|
@@ -20,7 +20,7 @@ const processEventQueue = async (context, eventType, eventSubType, startTime = n
|
|
|
20
20
|
try {
|
|
21
21
|
let eventTypeInstance;
|
|
22
22
|
const eventConfig = config.getEventConfig(eventType, eventSubType);
|
|
23
|
-
const [err, EventTypeClass] = resilientRequire(eventConfig);
|
|
23
|
+
const [err, EventTypeClass] = await resilientRequire(eventConfig);
|
|
24
24
|
if (!eventConfig || err || !(typeof EventTypeClass.constructor === "function")) {
|
|
25
25
|
cds.log(COMPONENT_NAME).error("No Implementation found in the provided configuration file.", {
|
|
26
26
|
eventType,
|
|
@@ -331,12 +331,24 @@ const _processEvent = async (eventTypeInstance, processContext, key, queueEntrie
|
|
|
331
331
|
}
|
|
332
332
|
};
|
|
333
333
|
|
|
334
|
-
const resilientRequire = (eventConfig) => {
|
|
334
|
+
const resilientRequire = async (eventConfig) => {
|
|
335
335
|
try {
|
|
336
336
|
const path = eventConfig?.impl;
|
|
337
337
|
const internal = eventConfig?.internalEvent;
|
|
338
|
-
const
|
|
339
|
-
|
|
338
|
+
const filePath = pathLib.join(internal ? __dirname : process.cwd(), path);
|
|
339
|
+
const fileExtension = pathLib.extname(filePath);
|
|
340
|
+
switch (fileExtension) {
|
|
341
|
+
case ".js":
|
|
342
|
+
return [null, require(filePath)];
|
|
343
|
+
case ".mjs":
|
|
344
|
+
return [null, (await import(`file://${filePath}`)).default];
|
|
345
|
+
case "":
|
|
346
|
+
try {
|
|
347
|
+
return [null, require(filePath)];
|
|
348
|
+
} catch {
|
|
349
|
+
return [null, (await import(`file://${filePath}`)).default];
|
|
350
|
+
}
|
|
351
|
+
}
|
|
340
352
|
} catch (err) {
|
|
341
353
|
return [err, null];
|
|
342
354
|
}
|
package/src/runner/runner.js
CHANGED
|
@@ -51,7 +51,10 @@ const _scheduleFunction = async (singleRunFn, periodicFn) => {
|
|
|
51
51
|
}
|
|
52
52
|
if (!singleRunDone) {
|
|
53
53
|
singleRunDone = true;
|
|
54
|
-
singleRunFn()
|
|
54
|
+
singleRunFn()
|
|
55
|
+
.then(periodicFn)
|
|
56
|
+
.catch(() => (singleRunDone = false));
|
|
57
|
+
return;
|
|
55
58
|
}
|
|
56
59
|
return periodicFn();
|
|
57
60
|
};
|
package/src/shared/common.js
CHANGED
|
@@ -90,10 +90,20 @@ const _acquireLockRedis = async (
|
|
|
90
90
|
|
|
91
91
|
const _renewLockRedis = async (context, fullKey, expiryTime, { value = "true" } = {}) => {
|
|
92
92
|
const client = await redis.createMainClientAndConnect(config.redisOptions);
|
|
93
|
-
|
|
93
|
+
let result = await client.set(fullKey, value, {
|
|
94
94
|
PX: Math.round(expiryTime),
|
|
95
95
|
XX: true,
|
|
96
96
|
});
|
|
97
|
+
|
|
98
|
+
if (result !== REDIS_COMMAND_OK) {
|
|
99
|
+
const readResult = await client.get(fullKey);
|
|
100
|
+
if (!readResult) {
|
|
101
|
+
result = await client.set(fullKey, value, {
|
|
102
|
+
PX: Math.round(expiryTime),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
97
107
|
return result === REDIS_COMMAND_OK;
|
|
98
108
|
};
|
|
99
109
|
|