@cap-js-community/event-queue 0.1.49 → 0.1.50
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/README.md +2 -2
- package/package.json +1 -1
- package/src/EventQueueProcessorBase.js +36 -31
- package/src/constants.js +5 -0
- package/src/processEventQueue.js +3 -1
- package/src/publishEvent.js +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ enhancing the overall performance of your application.
|
|
|
21
21
|
|
|
22
22
|
```js
|
|
23
23
|
const cds = require("@sap/cds");
|
|
24
|
-
const eventQueue = require("@
|
|
24
|
+
const eventQueue = require("@cap-js-community/event-queue");
|
|
25
25
|
|
|
26
26
|
cds.on("bootstrap", () => {
|
|
27
27
|
eventQueue.initialize({
|
|
@@ -86,7 +86,7 @@ Use the tables provided by this library. For that add the following to `package.
|
|
|
86
86
|
"cds": {
|
|
87
87
|
"requires": {
|
|
88
88
|
"cds-event-queue": {
|
|
89
|
-
"model": "@
|
|
89
|
+
"model": "@cap-js-community/event-queue"
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const cds = require("@sap/cds");
|
|
4
4
|
|
|
5
5
|
const { executeInNewTransaction } = require("./shared/cdsHelper");
|
|
6
|
-
const { EventProcessingStatus } = require("./constants");
|
|
6
|
+
const { EventProcessingStatus, TransactionMode } = require("./constants");
|
|
7
7
|
const distributedLock = require("./shared/distributedLock");
|
|
8
8
|
const EventQueueError = require("./EventQueueError");
|
|
9
9
|
const { arrayToFlatMap } = require("./shared/common");
|
|
@@ -48,7 +48,8 @@ class EventQueueProcessorBase {
|
|
|
48
48
|
this.__selectNextChunk = !!this.__config.checkForNextChunk;
|
|
49
49
|
this.__keepalivePromises = {};
|
|
50
50
|
this.__outdatedCheckEnabled = this.__config.eventOutdatedCheck ?? true;
|
|
51
|
-
this.
|
|
51
|
+
this.__transactionMode =
|
|
52
|
+
this.__config.transactionMode ?? TransactionMode.isolated;
|
|
52
53
|
this.__eventsWithExceededTries = [];
|
|
53
54
|
this.__emptyChunkSelected = false;
|
|
54
55
|
this.__lockAcquired = false;
|
|
@@ -175,7 +176,7 @@ class EventQueueProcessorBase {
|
|
|
175
176
|
eventType: this.__eventType,
|
|
176
177
|
eventSubType: this.__eventSubType,
|
|
177
178
|
});
|
|
178
|
-
this
|
|
179
|
+
this.#determineAndAddEventStatusToMap(
|
|
179
180
|
queueEntry.ID,
|
|
180
181
|
EventProcessingStatus.Done
|
|
181
182
|
);
|
|
@@ -191,12 +192,19 @@ class EventQueueProcessorBase {
|
|
|
191
192
|
clusterQueueEntries() {
|
|
192
193
|
Object.entries(this.__queueEntriesWithPayloadMap).forEach(
|
|
193
194
|
([key, { queueEntry, payload }]) => {
|
|
194
|
-
this.
|
|
195
|
+
this.addEntryToProcessingMap(key, queueEntry, payload);
|
|
195
196
|
}
|
|
196
197
|
);
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
|
|
200
|
+
/**
|
|
201
|
+
* This function allows to add entries to the process map. This function is needed if the function clusterQueueEntries
|
|
202
|
+
* is redefined. For each entry in the processing map the processEvent function will be called once.
|
|
203
|
+
* @param {String} key key for event
|
|
204
|
+
* @param {Object} queueEntry queueEntry which should be clustered with this key
|
|
205
|
+
* @param {Object} payload payload which should be clustered with this key
|
|
206
|
+
*/
|
|
207
|
+
addEntryToProcessingMap(key, queueEntry, payload) {
|
|
200
208
|
this.logger.debug("add entry to processing map", {
|
|
201
209
|
key,
|
|
202
210
|
queueEntry,
|
|
@@ -212,8 +220,8 @@ class EventQueueProcessorBase {
|
|
|
212
220
|
|
|
213
221
|
/**
|
|
214
222
|
* This function sets the status of multiple events to a given status. If the structure of queueEntryProcessingStatusTuple
|
|
215
|
-
* is not as expected all events will be set to error. The function respects the config
|
|
216
|
-
*
|
|
223
|
+
* is not as expected all events will be set to error. The function respects the config transactionMode. If
|
|
224
|
+
* transactionMode is isolated the status will be written to a dedicated map and returned afterwards to handle concurrent
|
|
217
225
|
* event processing.
|
|
218
226
|
* @param {Array} queueEntries which has been selected from event queue table and been modified by modifyQueueEntry
|
|
219
227
|
* @param {Array<Object>} queueEntryProcessingStatusTuple Array of tuple <queueEntryId, processingStatus>
|
|
@@ -227,14 +235,14 @@ class EventQueueProcessorBase {
|
|
|
227
235
|
eventType: this.__eventType,
|
|
228
236
|
eventSubType: this.__eventSubType,
|
|
229
237
|
});
|
|
230
|
-
const statusMap = this.
|
|
238
|
+
const statusMap = this.commitOnEventLevel ? {} : this.__statusMap;
|
|
231
239
|
try {
|
|
232
240
|
queueEntryProcessingStatusTuple.forEach(([id, processingStatus]) =>
|
|
233
|
-
this
|
|
241
|
+
this.#determineAndAddEventStatusToMap(id, processingStatus, statusMap)
|
|
234
242
|
);
|
|
235
243
|
} catch (error) {
|
|
236
244
|
queueEntries.forEach((queueEntry) =>
|
|
237
|
-
this
|
|
245
|
+
this.#determineAndAddEventStatusToMap(
|
|
238
246
|
queueEntry.ID,
|
|
239
247
|
EventProcessingStatus.Error,
|
|
240
248
|
statusMap
|
|
@@ -265,7 +273,7 @@ class EventQueueProcessorBase {
|
|
|
265
273
|
}
|
|
266
274
|
}
|
|
267
275
|
|
|
268
|
-
|
|
276
|
+
#determineAndAddEventStatusToMap(
|
|
269
277
|
id,
|
|
270
278
|
processingStatus,
|
|
271
279
|
statusMap = this.__statusMap
|
|
@@ -298,7 +306,7 @@ class EventQueueProcessorBase {
|
|
|
298
306
|
}
|
|
299
307
|
);
|
|
300
308
|
queueEntries.forEach((queueEntry) =>
|
|
301
|
-
this
|
|
309
|
+
this.#determineAndAddEventStatusToMap(
|
|
302
310
|
queueEntry.ID,
|
|
303
311
|
EventProcessingStatus.Error
|
|
304
312
|
)
|
|
@@ -324,11 +332,11 @@ class EventQueueProcessorBase {
|
|
|
324
332
|
eventType: this.__eventType,
|
|
325
333
|
eventSubType: this.__eventSubType,
|
|
326
334
|
});
|
|
327
|
-
this
|
|
335
|
+
this.#ensureOnlySelectedQueueEntries(statusMap);
|
|
328
336
|
if (!skipChecks) {
|
|
329
|
-
this
|
|
337
|
+
this.#ensureEveryQueueEntryHasStatus();
|
|
330
338
|
}
|
|
331
|
-
this
|
|
339
|
+
this.#ensureEveryStatusIsAllowed(statusMap);
|
|
332
340
|
|
|
333
341
|
const { success, failed, exceeded, invalidAttempts } = Object.entries(
|
|
334
342
|
statusMap
|
|
@@ -408,7 +416,7 @@ class EventQueueProcessorBase {
|
|
|
408
416
|
});
|
|
409
417
|
}
|
|
410
418
|
|
|
411
|
-
|
|
419
|
+
#ensureEveryQueueEntryHasStatus() {
|
|
412
420
|
this.__queueEntries.forEach((queueEntry) => {
|
|
413
421
|
if (
|
|
414
422
|
queueEntry.ID in this.__statusMap ||
|
|
@@ -424,14 +432,14 @@ class EventQueueProcessorBase {
|
|
|
424
432
|
queueEntry,
|
|
425
433
|
}
|
|
426
434
|
);
|
|
427
|
-
this
|
|
435
|
+
this.#determineAndAddEventStatusToMap(
|
|
428
436
|
queueEntry.ID,
|
|
429
437
|
EventProcessingStatus.Error
|
|
430
438
|
);
|
|
431
439
|
});
|
|
432
440
|
}
|
|
433
441
|
|
|
434
|
-
|
|
442
|
+
#ensureEveryStatusIsAllowed(statusMap) {
|
|
435
443
|
Object.entries(statusMap).forEach(([queueEntryId, status]) => {
|
|
436
444
|
if (
|
|
437
445
|
[
|
|
@@ -457,7 +465,7 @@ class EventQueueProcessorBase {
|
|
|
457
465
|
});
|
|
458
466
|
}
|
|
459
467
|
|
|
460
|
-
|
|
468
|
+
#ensureOnlySelectedQueueEntries(statusMap) {
|
|
461
469
|
Object.keys(statusMap).forEach((queueEntryId) => {
|
|
462
470
|
if (this.__queueEntriesMap[queueEntryId]) {
|
|
463
471
|
return;
|
|
@@ -484,7 +492,7 @@ class EventQueueProcessorBase {
|
|
|
484
492
|
}
|
|
485
493
|
);
|
|
486
494
|
this.__queueEntries.forEach((queueEntry) => {
|
|
487
|
-
this
|
|
495
|
+
this.#determineAndAddEventStatusToMap(
|
|
488
496
|
queueEntry.ID,
|
|
489
497
|
EventProcessingStatus.Error
|
|
490
498
|
);
|
|
@@ -500,7 +508,7 @@ class EventQueueProcessorBase {
|
|
|
500
508
|
eventSubType: this.__eventSubType,
|
|
501
509
|
}
|
|
502
510
|
);
|
|
503
|
-
this
|
|
511
|
+
this.#determineAndAddEventStatusToMap(
|
|
504
512
|
queueEntry.ID,
|
|
505
513
|
EventProcessingStatus.Error
|
|
506
514
|
);
|
|
@@ -574,7 +582,7 @@ class EventQueueProcessorBase {
|
|
|
574
582
|
}
|
|
575
583
|
|
|
576
584
|
const { exceededTries, openEvents } =
|
|
577
|
-
this
|
|
585
|
+
this.#filterExceededEvents(entries);
|
|
578
586
|
if (exceededTries.length) {
|
|
579
587
|
this.__eventsWithExceededTries = exceededTries;
|
|
580
588
|
}
|
|
@@ -620,7 +628,7 @@ class EventQueueProcessorBase {
|
|
|
620
628
|
return result;
|
|
621
629
|
}
|
|
622
630
|
|
|
623
|
-
|
|
631
|
+
#filterExceededEvents(events) {
|
|
624
632
|
return events.reduce(
|
|
625
633
|
(result, event) => {
|
|
626
634
|
if (event.attempts === this.__retryAttempts) {
|
|
@@ -819,13 +827,6 @@ class EventQueueProcessorBase {
|
|
|
819
827
|
this.__processTx = null;
|
|
820
828
|
}
|
|
821
829
|
|
|
822
|
-
get shouldTriggerRollback() {
|
|
823
|
-
return (
|
|
824
|
-
this.statusMapContainsError(this.__statusMap) ||
|
|
825
|
-
this.statusMapContainsError(this.__commitedStatusMap)
|
|
826
|
-
);
|
|
827
|
-
}
|
|
828
|
-
|
|
829
830
|
get logger() {
|
|
830
831
|
return this.__logger ?? this.__baseLogger;
|
|
831
832
|
}
|
|
@@ -875,7 +876,11 @@ class EventQueueProcessorBase {
|
|
|
875
876
|
}
|
|
876
877
|
|
|
877
878
|
get commitOnEventLevel() {
|
|
878
|
-
return this.
|
|
879
|
+
return this.__transactionMode === TransactionMode.isolated;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
get transactionMode() {
|
|
883
|
+
return this.__transactionMode;
|
|
879
884
|
}
|
|
880
885
|
|
|
881
886
|
get eventType() {
|
package/src/constants.js
CHANGED
package/src/processEventQueue.js
CHANGED
|
@@ -5,6 +5,7 @@ const pathLib = require("path");
|
|
|
5
5
|
const cds = require("@sap/cds");
|
|
6
6
|
|
|
7
7
|
const { getConfigInstance } = require("./config");
|
|
8
|
+
const { TransactionMode } = require("./constants");
|
|
8
9
|
const { limiter, Funnel } = require("./shared/common");
|
|
9
10
|
|
|
10
11
|
const EventQueueBase = require("./EventQueueProcessorBase");
|
|
@@ -136,7 +137,8 @@ const processEventQueue = async (
|
|
|
136
137
|
eventTypeInstance.handleErrorDuringClustering(err);
|
|
137
138
|
}
|
|
138
139
|
if (
|
|
139
|
-
eventTypeInstance.
|
|
140
|
+
eventTypeInstance.transactionMode !==
|
|
141
|
+
TransactionMode.alwaysCommit ||
|
|
140
142
|
Object.entries(eventTypeInstance.eventProcessingMap).some(
|
|
141
143
|
([key]) => eventTypeInstance.shouldRollbackTransaction(key)
|
|
142
144
|
)
|
package/src/publishEvent.js
CHANGED