@cap-js-community/event-queue 0.2.2 → 0.2.4

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.
@@ -4,32 +4,22 @@ const pathLib = require("path");
4
4
 
5
5
  const cds = require("@sap/cds");
6
6
 
7
- const { getConfigInstance } = require("./config");
7
+ const config = require("./config");
8
8
  const { TransactionMode } = require("./constants");
9
- const { limiter, Funnel } = require("./shared/common");
9
+ const { limiter } = require("./shared/common");
10
10
 
11
11
  const { executeInNewTransaction, TriggerRollback } = require("./shared/cdsHelper");
12
12
 
13
13
  const COMPONENT_NAME = "eventQueue/processEventQueue";
14
14
  const MAX_EXECUTION_TIME = 5 * 60 * 1000;
15
15
 
16
- const eventQueueRunner = async (context, events) => {
17
- const startTime = new Date();
18
- const funnel = new Funnel();
19
- await Promise.allSettled(
20
- events.map((event) =>
21
- funnel.run(event.load, async () => processEventQueue(context, event.type, event.subType, startTime))
22
- )
23
- );
24
- };
25
-
26
16
  const processEventQueue = async (context, eventType, eventSubType, startTime = new Date()) => {
27
17
  let iterationCounter = 0;
28
18
  let shouldContinue = true;
29
19
  let baseInstance;
30
20
  try {
31
21
  let eventTypeInstance;
32
- const eventConfig = getConfigInstance().getEventConfig(eventType, eventSubType);
22
+ const eventConfig = config.getEventConfig(eventType, eventSubType);
33
23
  const [err, EventTypeClass] = resilientRequire(eventConfig?.impl);
34
24
  if (!eventConfig || err || !(typeof EventTypeClass.constructor === "function")) {
35
25
  cds.log(COMPONENT_NAME).error("No Implementation found in the provided configuration file.", {
@@ -111,7 +101,7 @@ const processEventQueue = async (context, eventType, eventSubType, startTime = n
111
101
  }
112
102
  }
113
103
  } catch (err) {
114
- cds.log(COMPONENT_NAME).error("Processing event queue failed with unexpected error. Error:", err, {
104
+ cds.log(COMPONENT_NAME).error("Processing event queue failed with unexpected error.", err, {
115
105
  eventType,
116
106
  eventSubType,
117
107
  });
@@ -137,58 +127,67 @@ const reevaluateShouldContinue = (eventTypeInstance, iterationCounter, startTime
137
127
  // TODO: don't forget to release lock
138
128
  const processPeriodicEvent = async (eventTypeInstance) => {
139
129
  let queueEntry;
130
+ let processNext = true;
131
+
140
132
  try {
141
- await executeInNewTransaction(
142
- eventTypeInstance.context,
143
- `eventQueue-periodic-scheduleNext-${eventTypeInstance.eventType}##${eventTypeInstance.eventSubType}`,
144
- async (tx) => {
145
- eventTypeInstance.processEventContext = tx.context;
146
- const queueEntries = await eventTypeInstance.getQueueEntriesAndSetToInProgress();
147
- if (!queueEntries.length) {
148
- return;
149
- }
150
- if (queueEntries.length > 1) {
151
- queueEntry = await eventTypeInstance.handleDuplicatedPeriodicEventEntry(queueEntries);
152
- } else {
153
- queueEntry = queueEntries[0];
133
+ while (processNext) {
134
+ await executeInNewTransaction(
135
+ eventTypeInstance.context,
136
+ `eventQueue-periodic-scheduleNext-${eventTypeInstance.eventType}##${eventTypeInstance.eventSubType}`,
137
+ async (tx) => {
138
+ eventTypeInstance.processEventContext = tx.context;
139
+ const queueEntries = await eventTypeInstance.getQueueEntriesAndSetToInProgress();
140
+ if (!queueEntries.length) {
141
+ return;
142
+ }
143
+ if (queueEntries.length > 1) {
144
+ queueEntry = await eventTypeInstance.handleDuplicatedPeriodicEventEntry(queueEntries);
145
+ } else {
146
+ queueEntry = queueEntries[0];
147
+ }
148
+ processNext = await eventTypeInstance.scheduleNextPeriodEvent(queueEntry);
154
149
  }
155
- await eventTypeInstance.scheduleNextPeriodEvent(queueEntry);
156
- }
157
- );
150
+ );
158
151
 
159
- if (!queueEntry) {
160
- return;
161
- }
152
+ if (!queueEntry) {
153
+ return;
154
+ }
162
155
 
163
- await executeInNewTransaction(
164
- eventTypeInstance.context,
165
- `eventQueue-periodic-process-${eventTypeInstance.eventType}##${eventTypeInstance.eventSubType}`,
166
- async (tx) => {
167
- eventTypeInstance.processEventContext = tx.context;
168
- eventTypeInstance.setTxForEventProcessing(queueEntry.ID, cds.tx(tx.context));
169
- try {
170
- await eventTypeInstance.processEvent(tx.context, queueEntry.ID, [queueEntry]);
171
- } catch (err) {
172
- eventTypeInstance.handleErrorDuringPeriodicEventProcessing(err, queueEntry);
173
- throw new TriggerRollback();
174
- }
175
- if (
176
- eventTypeInstance.transactionMode !== TransactionMode.alwaysCommit ||
177
- eventTypeInstance.shouldRollbackTransaction(queueEntry.ID)
178
- ) {
179
- throw new TriggerRollback();
156
+ await executeInNewTransaction(
157
+ eventTypeInstance.context,
158
+ `eventQueue-periodic-process-${eventTypeInstance.eventType}##${eventTypeInstance.eventSubType}`,
159
+ async (tx) => {
160
+ eventTypeInstance.processEventContext = tx.context;
161
+ eventTypeInstance.setTxForEventProcessing(queueEntry.ID, cds.tx(tx.context));
162
+ try {
163
+ await eventTypeInstance.processPeriodicEvent(tx.context, queueEntry.ID, queueEntry);
164
+ } catch (err) {
165
+ eventTypeInstance.handleErrorDuringPeriodicEventProcessing(err, queueEntry);
166
+ throw new TriggerRollback();
167
+ }
168
+ if (
169
+ eventTypeInstance.transactionMode !== TransactionMode.alwaysCommit ||
170
+ eventTypeInstance.shouldRollbackTransaction(queueEntry.ID)
171
+ ) {
172
+ throw new TriggerRollback();
173
+ }
180
174
  }
181
- }
182
- );
175
+ );
183
176
 
184
- await executeInNewTransaction(
185
- eventTypeInstance.context,
186
- `eventQueue-periodic-setStatus-${eventTypeInstance.eventType}##${eventTypeInstance.eventSubType}`,
187
- async (tx) => {
188
- eventTypeInstance.processEventContext = tx.context;
189
- await eventTypeInstance.setPeriodicEventStatus(queueEntry.ID);
190
- }
191
- );
177
+ await executeInNewTransaction(
178
+ eventTypeInstance.context,
179
+ `eventQueue-periodic-setStatus-${eventTypeInstance.eventType}##${eventTypeInstance.eventSubType}`,
180
+ async (tx) => {
181
+ eventTypeInstance.processEventContext = tx.context;
182
+ await eventTypeInstance.setPeriodicEventStatus(queueEntry.ID);
183
+ }
184
+ );
185
+ }
186
+ } catch (err) {
187
+ cds.log(COMPONENT_NAME).error("Processing periodic events failed with unexpected error.", err, {
188
+ eventType: eventTypeInstance?.eventType,
189
+ eventSubType: eventTypeInstance?.eventSubType,
190
+ });
192
191
  } finally {
193
192
  await eventTypeInstance?.handleReleaseLock();
194
193
  }
@@ -269,5 +268,4 @@ const resilientRequire = (path) => {
269
268
 
270
269
  module.exports = {
271
270
  processEventQueue,
272
- eventQueueRunner,
273
271
  };
@@ -28,13 +28,12 @@ const EventQueueError = require("./EventQueueError");
28
28
  * @returns {Promise} Returns a promise which resolves to the result of the database insert operation.
29
29
  */
30
30
  const publishEvent = async (tx, events, skipBroadcast = false) => {
31
- const configInstance = config.getConfigInstance();
32
- if (!configInstance.initialized) {
31
+ if (!config.initialized) {
33
32
  throw EventQueueError.notInitialized();
34
33
  }
35
34
  const eventsForProcessing = Array.isArray(events) ? events : [events];
36
35
  for (const { type, subType, startAfter } of eventsForProcessing) {
37
- const eventConfig = configInstance.getEventConfig(type, subType);
36
+ const eventConfig = config.getEventConfig(type, subType);
38
37
  if (!eventConfig) {
39
38
  throw EventQueueError.unknownEventType(type, subType);
40
39
  }
@@ -47,7 +46,7 @@ const publishEvent = async (tx, events, skipBroadcast = false) => {
47
46
  }
48
47
  }
49
48
  tx._skipEventQueueBroadcase = skipBroadcast;
50
- const result = await tx.run(INSERT.into(configInstance.tableNameEventQueue).entries(eventsForProcessing));
49
+ const result = await tx.run(INSERT.into(config.tableNameEventQueue).entries(eventsForProcessing));
51
50
  tx._skipEventQueueBroadcase = false;
52
51
  return result;
53
52
  };
@@ -11,7 +11,7 @@ const COMPONENT_NAME = "eventQueue/redisPubSub";
11
11
  let subscriberClientPromise;
12
12
 
13
13
  const initEventQueueRedisSubscribe = () => {
14
- if (subscriberClientPromise || !config.getConfigInstance().redisEnabled) {
14
+ if (subscriberClientPromise || !config.redisEnabled) {
15
15
  return;
16
16
  }
17
17
  redis.subscribeRedisChannel(EVENT_MESSAGE_CHANNEL, messageHandlerProcessEvents);
@@ -36,9 +36,8 @@ const messageHandlerProcessEvents = async (messageData) => {
36
36
 
37
37
  const broadcastEvent = async (tenantId, type, subType) => {
38
38
  const logger = cds.log(COMPONENT_NAME);
39
- const configInstance = config.getConfigInstance();
40
- if (!configInstance.redisEnabled) {
41
- if (configInstance.registerAsEventProcessor) {
39
+ if (!config.redisEnabled) {
40
+ if (config.registerAsEventProcessor) {
42
41
  await runEventCombinationForTenant(tenantId, type, subType);
43
42
  }
44
43
  return;
@@ -49,7 +48,10 @@ const broadcastEvent = async (tenantId, type, subType) => {
49
48
  [type, subType].join("##")
50
49
  );
51
50
  if (result) {
52
- logger.info("skip publish redis event as no lock is available");
51
+ logger.info("skip publish redis event as no lock is available", {
52
+ type,
53
+ subType,
54
+ });
53
55
  return;
54
56
  }
55
57
  logger.debug("publishing redis event", {
@@ -59,7 +61,7 @@ const broadcastEvent = async (tenantId, type, subType) => {
59
61
  });
60
62
  await redis.publishMessage(EVENT_MESSAGE_CHANNEL, JSON.stringify({ tenantId, type, subType }));
61
63
  } catch (err) {
62
- logger.error(`publish event failed with error: ${err.toString()}`, {
64
+ logger.error("publish event failed!", err, {
63
65
  tenantId,
64
66
  type,
65
67
  subType,
package/src/runner.js CHANGED
@@ -3,8 +3,8 @@
3
3
  const { randomUUID } = require("crypto");
4
4
 
5
5
  const eventQueueConfig = require("./config");
6
- const { eventQueueRunner, processEventQueue } = require("./processEventQueue");
7
- const { getWorkerPoolInstance } = require("./shared/WorkerQueue");
6
+ const { processEventQueue } = require("./processEventQueue");
7
+ const WorkerQueue = require("./shared/WorkerQueue");
8
8
  const cdsHelper = require("./shared/cdsHelper");
9
9
  const distributedLock = require("./shared/distributedLock");
10
10
  const SetIntervalDriftSafe = require("./shared/SetIntervalDriftSafe");
@@ -19,8 +19,9 @@ const EVENT_QUEUE_RUN_PERIODIC_EVENT = "EVENT_QUEUE_RUN_PERIODIC_EVENT";
19
19
  const OFFSET_FIRST_RUN = 10 * 1000;
20
20
 
21
21
  let tenantIdHash;
22
+ let singleRunDone;
22
23
 
23
- const singleTenant = () => _scheduleFunction(_checkPeriodicEventsSingleTenant, _executeRunForTenant);
24
+ const singleTenant = () => _scheduleFunction(_checkPeriodicEventsSingleTenant, _singleTenantDb);
24
25
 
25
26
  const multiTenancyDb = () => _scheduleFunction(_multiTenancyPeriodicEvents, _multiTenancyDb);
26
27
 
@@ -28,8 +29,7 @@ const multiTenancyRedis = () => _scheduleFunction(_multiTenancyPeriodicEvents, _
28
29
 
29
30
  const _scheduleFunction = async (singleRunFn, periodicFn) => {
30
31
  const logger = cds.log(COMPONENT_NAME);
31
- const configInstance = eventQueueConfig.getConfigInstance();
32
- const eventsForAutomaticRun = configInstance.allEvents;
32
+ const eventsForAutomaticRun = eventQueueConfig.allEvents;
33
33
  if (!eventsForAutomaticRun.length) {
34
34
  logger.warn("no events for automatic run are configured - skipping runner registration");
35
35
  return;
@@ -37,10 +37,14 @@ const _scheduleFunction = async (singleRunFn, periodicFn) => {
37
37
 
38
38
  const fnWithRunningCheck = () => {
39
39
  const logger = cds.log(COMPONENT_NAME);
40
- if (configInstance.isRunnerDeactivated) {
40
+ if (eventQueueConfig.isRunnerDeactivated) {
41
41
  logger.info("runner is deactivated via config variable. Skipping this run.");
42
42
  return;
43
43
  }
44
+ if (!singleRunDone) {
45
+ singleRunDone = true;
46
+ singleRunFn().catch(() => (singleRunDone = false));
47
+ }
44
48
  return periodicFn();
45
49
  };
46
50
 
@@ -51,9 +55,8 @@ const _scheduleFunction = async (singleRunFn, periodicFn) => {
51
55
  });
52
56
 
53
57
  setTimeout(() => {
54
- singleRunFn();
55
58
  fnWithRunningCheck();
56
- const intervalRunner = new SetIntervalDriftSafe(configInstance.runInterval);
59
+ const intervalRunner = new SetIntervalDriftSafe(eventQueueConfig.runInterval);
57
60
  intervalRunner.run(fnWithRunningCheck);
58
61
  }, offsetDependingOnLastRun).unref();
59
62
  };
@@ -63,7 +66,7 @@ const _multiTenancyRedis = async () => {
63
66
  const emptyContext = new cds.EventContext({});
64
67
  logger.info("executing event queue run for multi instance and tenant");
65
68
  const tenantIds = await cdsHelper.getAllTenantIds();
66
- _checkAndTriggerPriodicEventUpdate(tenantIds);
69
+ _checkAndTriggerPeriodicEventUpdate(tenantIds);
67
70
 
68
71
  const runId = await _acquireRunId(emptyContext);
69
72
 
@@ -72,10 +75,10 @@ const _multiTenancyRedis = async () => {
72
75
  return;
73
76
  }
74
77
 
75
- _executeAllTenants(tenantIds, runId);
78
+ return _executeEventsAllTenants(tenantIds, runId);
76
79
  };
77
80
 
78
- const _checkAndTriggerPriodicEventUpdate = (tenantIds) => {
81
+ const _checkAndTriggerPeriodicEventUpdate = (tenantIds) => {
79
82
  const hash = hashStringTo32Bit(JSON.stringify(tenantIds));
80
83
  if (!tenantIdHash) {
81
84
  tenantIdHash = hash;
@@ -84,25 +87,52 @@ const _checkAndTriggerPriodicEventUpdate = (tenantIds) => {
84
87
  if (tenantIdHash && tenantIdHash !== hash) {
85
88
  cds.log(COMPONENT_NAME).info("tenant id hash changed, triggering updating periodic events!");
86
89
  _multiTenancyPeriodicEvents().catch((err) => {
87
- cds.log(COMPONENT_NAME).error("Error during triggering updating periodic events! Error:", err);
90
+ cds.log(COMPONENT_NAME).error("Error during triggering updating periodic events!", err);
88
91
  });
89
92
  }
90
93
  };
91
94
 
92
- const _executeAllTenantsGeneric = (tenantIds, runId, fn) => {
93
- const configInstance = eventQueueConfig.getConfigInstance();
94
- const workerQueueInstance = getWorkerPoolInstance();
95
+ const _executeEventsAllTenants = (tenantIds, runId) => {
96
+ const events = eventQueueConfig.allEvents;
97
+ const promises = [];
95
98
  tenantIds.forEach((tenantId) => {
96
- workerQueueInstance.addToQueue(async () => {
99
+ events.forEach((event) => {
100
+ promises.push(
101
+ WorkerQueue.instance.addToQueue(event.load, async () => {
102
+ try {
103
+ const lockId = `${runId}_${event.type}_${event.subType}`;
104
+ const tenantContext = new cds.EventContext({ tenant: tenantId });
105
+ const couldAcquireLock = await distributedLock.acquireLock(tenantContext, lockId, {
106
+ expiryTime: eventQueueConfig.runInterval * 0.95,
107
+ });
108
+ if (!couldAcquireLock) {
109
+ return;
110
+ }
111
+ await runEventCombinationForTenant(tenantId, event.type, event.subType, true);
112
+ } catch (err) {
113
+ cds.log(COMPONENT_NAME).error("executing event-queue run for tenant failed", {
114
+ tenantId,
115
+ });
116
+ }
117
+ })
118
+ );
119
+ });
120
+ });
121
+ return promises;
122
+ };
123
+
124
+ const _executePeriodicEventsAllTenants = (tenantIds, runId) => {
125
+ tenantIds.forEach((tenantId) => {
126
+ WorkerQueue.instance.addToQueue(1, async () => {
97
127
  try {
98
128
  const tenantContext = new cds.EventContext({ tenant: tenantId });
99
129
  const couldAcquireLock = await distributedLock.acquireLock(tenantContext, runId, {
100
- expiryTime: configInstance.runInterval * 0.95,
130
+ expiryTime: eventQueueConfig.runInterval * 0.95,
101
131
  });
102
132
  if (!couldAcquireLock) {
103
133
  return;
104
134
  }
105
- await fn(tenantId, runId);
135
+ await _checkPeriodicEventsSingleTenant(tenantId);
106
136
  } catch (err) {
107
137
  cds.log(COMPONENT_NAME).error("executing event-queue run for tenant failed", {
108
138
  tenantId,
@@ -112,49 +142,33 @@ const _executeAllTenantsGeneric = (tenantIds, runId, fn) => {
112
142
  });
113
143
  };
114
144
 
115
- const _executeAllTenants = (tenantIds, runId) => _executeAllTenantsGeneric(tenantIds, runId, _executeRunForTenant);
116
-
117
- const _executePeriodicEventsAllTenants = (tenantIds, runId) =>
118
- _executeAllTenantsGeneric(tenantIds, runId, _checkPeriodicEventsSingleTenant);
119
-
120
- const _executeRunForTenant = async (tenantId, runId) => {
121
- const logger = cds.log(COMPONENT_NAME);
122
- const configInstance = eventQueueConfig.getConfigInstance();
123
- try {
124
- const eventsForAutomaticRun = configInstance.allEvents;
125
- const subdomain = await cdsHelper.getSubdomainForTenantId(tenantId);
126
- const context = new cds.EventContext({
127
- tenant: tenantId,
128
- // NOTE: we need this because of logging otherwise logs would not contain the subdomain
129
- http: { req: { authInfo: { getSubdomain: () => subdomain } } },
130
- });
131
- cds.context = context;
132
- logger.info("executing eventQueue run", {
133
- tenantId,
134
- subdomain,
135
- ...(runId ? { runId } : null),
136
- });
137
- await eventQueueRunner(context, eventsForAutomaticRun);
138
- } catch (err) {
139
- logger.error(`Couldn't process eventQueue for tenant! Next try after defined interval. Error: ${err}`, {
140
- tenantId,
141
- redisEnabled: configInstance.redisEnabled,
145
+ const _singleTenantDb = async (tenantId) => {
146
+ const events = eventQueueConfig.allEvents;
147
+ events.forEach((event) => {
148
+ WorkerQueue.instance.addToQueue(event.load, async () => {
149
+ try {
150
+ await runEventCombinationForTenant(tenantId, event.type, event.subType, true);
151
+ } catch (err) {
152
+ cds.log(COMPONENT_NAME).error("executing event-queue run for tenant failed", {
153
+ tenantId,
154
+ redisEnabled: eventQueueConfig.redisEnabled,
155
+ });
156
+ }
142
157
  });
143
- }
158
+ });
144
159
  };
145
160
 
146
161
  const _acquireRunId = async (context) => {
147
- const configInstance = eventQueueConfig.getConfigInstance();
148
162
  let runId = randomUUID();
149
163
  const couldSetValue = await distributedLock.setValueWithExpire(context, EVENT_QUEUE_RUN_ID, runId, {
150
164
  tenantScoped: false,
151
- expiryTime: configInstance.runInterval * 0.95,
165
+ expiryTime: eventQueueConfig.runInterval * 0.95,
152
166
  });
153
167
 
154
168
  if (couldSetValue) {
155
169
  await distributedLock.setValueWithExpire(context, EVENT_QUEUE_RUN_TS, new Date().toISOString(), {
156
170
  tenantScoped: false,
157
- expiryTime: configInstance.runInterval,
171
+ expiryTime: eventQueueConfig.runInterval,
158
172
  overrideValue: true,
159
173
  });
160
174
  } else {
@@ -167,13 +181,12 @@ const _acquireRunId = async (context) => {
167
181
  };
168
182
 
169
183
  const _calculateOffsetForFirstRun = async () => {
170
- const configInstance = eventQueueConfig.getConfigInstance();
171
184
  let offsetDependingOnLastRun = OFFSET_FIRST_RUN;
172
185
  const now = Date.now();
173
186
  // NOTE: this is only supported with Redis, because this is a tenant agnostic information
174
187
  // currently there is no proper place to store this information beside t0 schema
175
188
  try {
176
- if (configInstance.redisEnabled) {
189
+ if (eventQueueConfig.redisEnabled) {
177
190
  const dummyContext = new cds.EventContext({});
178
191
  let lastRunTs = await distributedLock.checkLockExistsAndReturnValue(dummyContext, EVENT_QUEUE_RUN_TS, {
179
192
  tenantScoped: false,
@@ -182,7 +195,7 @@ const _calculateOffsetForFirstRun = async () => {
182
195
  const ts = new Date(now).toISOString();
183
196
  const couldSetValue = await distributedLock.setValueWithExpire(dummyContext, EVENT_QUEUE_RUN_TS, ts, {
184
197
  tenantScoped: false,
185
- expiryTime: configInstance.runInterval,
198
+ expiryTime: eventQueueConfig.runInterval,
186
199
  });
187
200
  if (couldSetValue) {
188
201
  lastRunTs = ts;
@@ -192,20 +205,17 @@ const _calculateOffsetForFirstRun = async () => {
192
205
  });
193
206
  }
194
207
  }
195
- offsetDependingOnLastRun = new Date(lastRunTs).getTime() + configInstance.runInterval - now;
208
+ offsetDependingOnLastRun = new Date(lastRunTs).getTime() + eventQueueConfig.runInterval - now;
196
209
  }
197
210
  } catch (err) {
198
211
  cds
199
212
  .log(COMPONENT_NAME)
200
- .error(
201
- "calculating offset for first run failed, falling back to default. Runs might be out-of-sync. Error:",
202
- err
203
- );
213
+ .error("calculating offset for first run failed, falling back to default. Runs might be out-of-sync.", err);
204
214
  }
205
215
  return offsetDependingOnLastRun;
206
216
  };
207
217
 
208
- const runEventCombinationForTenant = async (tenantId, type, subType) => {
218
+ const runEventCombinationForTenant = async (tenantId, type, subType, skipWorkerPool) => {
209
219
  try {
210
220
  const subdomain = await getSubdomainForTenantId(tenantId);
211
221
  const context = new cds.EventContext({
@@ -214,7 +224,15 @@ const runEventCombinationForTenant = async (tenantId, type, subType) => {
214
224
  http: { req: { authInfo: { getSubdomain: () => subdomain } } },
215
225
  });
216
226
  cds.context = context;
217
- getWorkerPoolInstance().addToQueue(async () => await processEventQueue(context, type, subType));
227
+ if (skipWorkerPool) {
228
+ return await processEventQueue(context, type, subType);
229
+ } else {
230
+ const config = eventQueueConfig.getEventConfig(type, subType);
231
+ return await WorkerQueue.instance.addToQueue(
232
+ config.load,
233
+ async () => await processEventQueue(context, type, subType)
234
+ );
235
+ }
218
236
  } catch (err) {
219
237
  const logger = cds.log(COMPONENT_NAME);
220
238
  logger.error("error executing event combination for tenant", err, {
@@ -230,12 +248,10 @@ const _multiTenancyDb = async () => {
230
248
  try {
231
249
  logger.info("executing event queue run for single instance and multi tenant");
232
250
  const tenantIds = await cdsHelper.getAllTenantIds();
233
- _checkAndTriggerPriodicEventUpdate(tenantIds);
234
- _executeAllTenants(tenantIds, EVENT_QUEUE_RUN_ID);
251
+ _checkAndTriggerPeriodicEventUpdate(tenantIds);
252
+ return _executeEventsAllTenants(tenantIds, EVENT_QUEUE_RUN_ID);
235
253
  } catch (err) {
236
- logger.error(
237
- `Couldn't fetch tenant ids for event queue processing! Next try after defined interval. Error: ${err}`
238
- );
254
+ logger.error("Couldn't fetch tenant ids for event queue processing! Next try after defined interval.", err);
239
255
  }
240
256
  };
241
257
 
@@ -246,15 +262,18 @@ const _multiTenancyPeriodicEvents = async () => {
246
262
  const tenantIds = await cdsHelper.getAllTenantIds();
247
263
  _executePeriodicEventsAllTenants(tenantIds, EVENT_QUEUE_RUN_PERIODIC_EVENT);
248
264
  } catch (err) {
249
- logger.error(`Couldn't fetch tenant ids for updating periodic event processing! Error: ${err}`);
265
+ logger.error("Couldn't fetch tenant ids for updating periodic event processing!", err);
250
266
  }
251
267
  };
252
268
 
253
269
  const _checkPeriodicEventsSingleTenant = async (tenantId) => {
254
270
  const logger = cds.log(COMPONENT_NAME);
255
- const configInstance = eventQueueConfig.getConfigInstance();
256
- if (!configInstance.updatePeriodicEvents) {
257
- logger.info("updating of periodic events is disabled");
271
+ if (!eventQueueConfig.updatePeriodicEvents || !eventQueueConfig.periodicEvents.length) {
272
+ logger.info("updating of periodic events is disabled or no periodic events configured", {
273
+ updateEnabled: eventQueueConfig.updatePeriodicEvents,
274
+ events: eventQueueConfig.periodicEvents.length,
275
+ });
276
+ return;
258
277
  }
259
278
  try {
260
279
  const subdomain = await cdsHelper.getSubdomainForTenantId(tenantId);
@@ -272,9 +291,9 @@ const _checkPeriodicEventsSingleTenant = async (tenantId) => {
272
291
  await periodicEvents.checkAndInsertPeriodicEvents(tx.context);
273
292
  });
274
293
  } catch (err) {
275
- logger.error(`Couldn't process eventQueue for tenant! Next try after defined interval. Error: ${err}`, {
294
+ logger.error("Couldn't update periodic events for tenant! Next try after defined interval.", err, {
276
295
  tenantId,
277
- redisEnabled: configInstance.redisEnabled,
296
+ redisEnabled: eventQueueConfig.redisEnabled,
278
297
  });
279
298
  }
280
299
  };