@cap-js-community/event-queue 1.6.4 → 1.6.6
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.6.
|
|
3
|
+
"version": "1.6.6",
|
|
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",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"test:all:coverage": "jest --runInBand --forceExit --collect-coverage",
|
|
28
28
|
"test:prepare": "npm run build:ci --prefix=./test-integration/_env",
|
|
29
29
|
"test:deploySchema": "node test-integration/_env/srv/hana/deploy.js",
|
|
30
|
-
"test:cleanSchemas": "node test-integration/_env/srv/hana/
|
|
30
|
+
"test:cleanSchemas": "node test-integration/_env/srv/hana/deleteTestSchema.js ",
|
|
31
31
|
"lint": "npm run eslint && npm run prettier",
|
|
32
32
|
"lint:ci": "npm run eslint:ci && npm run prettier:ci",
|
|
33
33
|
"eslint": "eslint --fix .",
|
|
@@ -24,6 +24,7 @@ const TRIES_FOR_EXCEEDED_EVENTS = 3;
|
|
|
24
24
|
const EVENT_START_AFTER_HEADROOM = 3 * 1000;
|
|
25
25
|
const ETAG_CHECK_AFTER_MIN = 10;
|
|
26
26
|
const SUFFIX_PERIODIC = "_PERIODIC";
|
|
27
|
+
const DEFAULT_RETRY_AFTER = 5 * 60 * 1000;
|
|
27
28
|
|
|
28
29
|
class EventQueueProcessorBase {
|
|
29
30
|
#eventsWithExceededTries = [];
|
|
@@ -37,6 +38,7 @@ class EventQueueProcessorBase {
|
|
|
37
38
|
#eventConfig;
|
|
38
39
|
#isPeriodic;
|
|
39
40
|
#lastSuccessfulRunTimestamp;
|
|
41
|
+
#retryFailedAfter;
|
|
40
42
|
|
|
41
43
|
constructor(context, eventType, eventSubType, config) {
|
|
42
44
|
this.__context = context;
|
|
@@ -57,6 +59,7 @@ class EventQueueProcessorBase {
|
|
|
57
59
|
if (this.__parallelEventProcessing > LIMIT_PARALLEL_EVENT_PROCESSING) {
|
|
58
60
|
this.__parallelEventProcessing = LIMIT_PARALLEL_EVENT_PROCESSING;
|
|
59
61
|
}
|
|
62
|
+
this.#retryFailedAfter = this.#eventConfig.retryFailedAfter ?? DEFAULT_RETRY_AFTER;
|
|
60
63
|
// NOTE: keep the feature, this might be needed again
|
|
61
64
|
this.__concurrentEventProcessing = false;
|
|
62
65
|
this.__startTime = this.#eventConfig.startTime ?? new Date();
|
|
@@ -454,11 +457,23 @@ class EventQueueProcessorBase {
|
|
|
454
457
|
if (!eventIds.length) {
|
|
455
458
|
continue;
|
|
456
459
|
}
|
|
460
|
+
let startAfter;
|
|
461
|
+
if (status === EventProcessingStatus.Error) {
|
|
462
|
+
startAfter = new Date(Date.now() + this.#retryFailedAfter);
|
|
463
|
+
this.#eventSchedulerInstance.scheduleEvent(
|
|
464
|
+
this.__context.tenant,
|
|
465
|
+
this.#eventType,
|
|
466
|
+
this.#eventSubType,
|
|
467
|
+
startAfter
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
|
|
457
471
|
await tx.run(
|
|
458
472
|
UPDATE.entity(this.#config.tableNameEventQueue)
|
|
459
473
|
.set({
|
|
460
474
|
status: status,
|
|
461
475
|
lastAttemptTimestamp: ts,
|
|
476
|
+
...(status === EventProcessingStatus.Error ? { startAfter: startAfter.toISOString() } : {}),
|
|
462
477
|
})
|
|
463
478
|
.where("ID IN", eventIds)
|
|
464
479
|
);
|
|
@@ -552,7 +567,8 @@ class EventQueueProcessorBase {
|
|
|
552
567
|
*/
|
|
553
568
|
async getQueueEntriesAndSetToInProgress() {
|
|
554
569
|
let result = [];
|
|
555
|
-
const
|
|
570
|
+
const baseDate = Date.now();
|
|
571
|
+
const refDateStartAfter = new Date(baseDate + this.#config.runInterval * 1.2);
|
|
556
572
|
await executeInNewTransaction(this.__baseContext, "eventQueue-getQueueEntriesAndSetToInProgress", async (tx) => {
|
|
557
573
|
const entries = await tx.run(
|
|
558
574
|
SELECT.from(this.#config.tableNameEventQueue)
|
|
@@ -574,7 +590,7 @@ class EventQueueProcessorBase {
|
|
|
574
590
|
"OR lastAttemptTimestamp IS NULL ) OR ( status =",
|
|
575
591
|
EventProcessingStatus.InProgress,
|
|
576
592
|
"AND lastAttemptTimestamp <=",
|
|
577
|
-
new Date(
|
|
593
|
+
new Date(baseDate - this.#config.globalTxTimeout).toISOString(),
|
|
578
594
|
") )",
|
|
579
595
|
]
|
|
580
596
|
: [
|
|
@@ -585,7 +601,7 @@ class EventQueueProcessorBase {
|
|
|
585
601
|
") OR ( status =",
|
|
586
602
|
EventProcessingStatus.InProgress,
|
|
587
603
|
"AND lastAttemptTimestamp <=",
|
|
588
|
-
new Date(
|
|
604
|
+
new Date(baseDate - this.#config.globalTxTimeout).toISOString(),
|
|
589
605
|
") )",
|
|
590
606
|
])
|
|
591
607
|
)
|
package/src/runner/runner.js
CHANGED
|
@@ -142,7 +142,8 @@ const _executeEventsAllTenantsRedis = async (tenantIds) => {
|
|
|
142
142
|
if (!entries.length) {
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
145
|
-
|
|
145
|
+
// Do not wait until this is finished - as broadcastEvent has a retry mechanism and can delay this loop
|
|
146
|
+
redisPub.broadcastEvent(tenantId, entries).catch((err) => {
|
|
146
147
|
logger.error("broadcasting event failed", err, {
|
|
147
148
|
tenantId,
|
|
148
149
|
entries: entries.length,
|