@cap-js-community/event-queue 1.10.1 → 1.10.3
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": "@cap-js-community/event-queue",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.3",
|
|
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",
|
|
@@ -1019,11 +1019,18 @@ class EventQueueProcessorBase {
|
|
|
1019
1019
|
async scheduleNextPeriodEvent(queueEntry) {
|
|
1020
1020
|
const intervalInMs = this.#eventConfig.cron ? null : this.#eventConfig.interval * 1000;
|
|
1021
1021
|
const next = this.#calculateCronDates();
|
|
1022
|
+
let newStartAfter;
|
|
1023
|
+
|
|
1024
|
+
if (this.#eventConfig.cron) {
|
|
1025
|
+
newStartAfter = next.getTime() + this.#calculateRandomOffset();
|
|
1026
|
+
} else {
|
|
1027
|
+
newStartAfter = new Date(queueEntry.startAfter).getTime() + intervalInMs + this.#calculateRandomOffset();
|
|
1028
|
+
}
|
|
1022
1029
|
|
|
1023
1030
|
const newEvent = {
|
|
1024
1031
|
type: this.#eventType,
|
|
1025
1032
|
subType: this.#eventSubType,
|
|
1026
|
-
startAfter:
|
|
1033
|
+
startAfter: new Date(newStartAfter),
|
|
1027
1034
|
};
|
|
1028
1035
|
const { relative } = this.#eventSchedulerInstance.calculateOffset(
|
|
1029
1036
|
this.#eventType,
|
|
@@ -1071,6 +1078,15 @@ class EventQueueProcessorBase {
|
|
|
1071
1078
|
}
|
|
1072
1079
|
}
|
|
1073
1080
|
|
|
1081
|
+
#calculateRandomOffset() {
|
|
1082
|
+
const offset = this.#eventConfig.randomOffset ?? this.#config.randomOffsetPeriodicEvents;
|
|
1083
|
+
if (!offset) {
|
|
1084
|
+
return 0;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
return Math.floor(Math.random() * offset) * 1000;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1074
1090
|
async handleDuplicatedPeriodicEventEntry(queueEntries) {
|
|
1075
1091
|
this.logger.error("More than one open events for the same configuration which is not allowed!", {
|
|
1076
1092
|
eventType: this.#eventType,
|
package/src/config.js
CHANGED
|
@@ -75,6 +75,7 @@ const ALLOWED_EVENT_OPTIONS_PERIODIC_EVENT = [
|
|
|
75
75
|
"cron",
|
|
76
76
|
"utc",
|
|
77
77
|
"useCronTimezone",
|
|
78
|
+
"randomOffset",
|
|
78
79
|
];
|
|
79
80
|
|
|
80
81
|
class Config {
|
|
@@ -108,6 +109,7 @@ class Config {
|
|
|
108
109
|
#unsubscribeHandlers = [];
|
|
109
110
|
#unsubscribedTenants = {};
|
|
110
111
|
#cronTimezone;
|
|
112
|
+
#randomOffsetPeriodicEvents;
|
|
111
113
|
#redisNamespace;
|
|
112
114
|
#publishEventBlockList;
|
|
113
115
|
#crashOnRedisUnavailable;
|
|
@@ -167,7 +169,15 @@ class Config {
|
|
|
167
169
|
return { type: "string", value: str };
|
|
168
170
|
}
|
|
169
171
|
|
|
170
|
-
|
|
172
|
+
#normalizeSubType(rawSubType) {
|
|
173
|
+
const [serviceName, actionName] = rawSubType.split(".");
|
|
174
|
+
const actionSpecificCall = this.getCdsOutboxEventSpecificConfig(serviceName, actionName);
|
|
175
|
+
return actionSpecificCall ? rawSubType : serviceName;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
shouldBeProcessedInThisApplication(type, rawSubType) {
|
|
179
|
+
const subType = this.#normalizeSubType(rawSubType);
|
|
180
|
+
|
|
171
181
|
const config = this.#eventMap[this.generateKey(type, subType)];
|
|
172
182
|
const appNameConfig = config._appNameMap;
|
|
173
183
|
const appInstanceConfig = config._appInstancesMap;
|
|
@@ -815,6 +825,14 @@ class Config {
|
|
|
815
825
|
this.#cronTimezone = value;
|
|
816
826
|
}
|
|
817
827
|
|
|
828
|
+
get randomOffsetPeriodicEvents() {
|
|
829
|
+
return this.#randomOffsetPeriodicEvents;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
set randomOffsetPeriodicEvents(value) {
|
|
833
|
+
this.#randomOffsetPeriodicEvents = value;
|
|
834
|
+
}
|
|
835
|
+
|
|
818
836
|
get instanceLoadLimit() {
|
|
819
837
|
return this.#instanceLoadLimit;
|
|
820
838
|
}
|
package/src/initialize.js
CHANGED
|
@@ -42,6 +42,7 @@ const CONFIG_VARS = [
|
|
|
42
42
|
["insertEventsBeforeCommit", true],
|
|
43
43
|
["enableTelemetry", true],
|
|
44
44
|
["cronTimezone", null],
|
|
45
|
+
["randomOffsetPeriodicEvents", null],
|
|
45
46
|
["redisNamespace", null],
|
|
46
47
|
["publishEventBlockList", true],
|
|
47
48
|
["crashOnRedisUnavailable", false],
|
|
@@ -68,6 +69,7 @@ const CONFIG_VARS = [
|
|
|
68
69
|
* @param {boolean} [options.insertEventsBeforeCommit=true] - Insert events into the queue before committing the transaction.
|
|
69
70
|
* @param {boolean} [options.enableTelemetry=false] - Enable telemetry for CAP.
|
|
70
71
|
* @param {string} [options.cronTimezone=null] - Default timezone for cron jobs.
|
|
72
|
+
* @param {string} [options.randomOffsetPeriodicEvents=null] - Default random offset for periodic events.
|
|
71
73
|
* @param {string} [options.publishEventBlockList=true] - If redis is available event blocklist is distributed to all application instances
|
|
72
74
|
* @param {string} [options.crashOnRedisUnavailable=true] - If enabled an error is thrown if the redis connection check is not successful
|
|
73
75
|
*/
|
|
@@ -47,7 +47,6 @@ function outboxed(srv, customOpts) {
|
|
|
47
47
|
customOpts || {}
|
|
48
48
|
);
|
|
49
49
|
config.addCAPOutboxEventBase(srv.name, outboxOpts);
|
|
50
|
-
// TODO: check req.event ?? req.method
|
|
51
50
|
const specificSettings = config.getCdsOutboxEventSpecificConfig(srv.name, req.event);
|
|
52
51
|
if (specificSettings) {
|
|
53
52
|
outboxOpts = config.addCAPOutboxEventSpecificAction(srv.name, req.event);
|
package/src/redis/redisSub.js
CHANGED
|
@@ -40,11 +40,18 @@ const _messageHandlerProcessEvents = async (messageData) => {
|
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
const [serviceNameOrSubType, actionName] = subType.split(".");
|
|
43
44
|
if (!config.getEventConfig(type, subType)) {
|
|
44
45
|
if (config.isCapOutboxEvent(type)) {
|
|
45
46
|
try {
|
|
46
|
-
const service = await cds.connect.to(
|
|
47
|
+
const service = await cds.connect.to(serviceNameOrSubType);
|
|
47
48
|
cds.outboxed(service);
|
|
49
|
+
if (actionName) {
|
|
50
|
+
const specificSettings = config.getCdsOutboxEventSpecificConfig(serviceNameOrSubType, actionName);
|
|
51
|
+
if (specificSettings) {
|
|
52
|
+
config.addCAPOutboxEventSpecificAction(serviceNameOrSubType, actionName);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
48
55
|
} catch (err) {
|
|
49
56
|
logger.warn("could not connect to outboxed service", err, {
|
|
50
57
|
type,
|