@cap-js-community/event-queue 1.10.7 → 1.10.9
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.9",
|
|
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",
|
package/src/runner/openEvents.js
CHANGED
|
@@ -38,34 +38,27 @@ const getOpenQueueEntries = async (tx, filterAppSpecificEvents = true) => {
|
|
|
38
38
|
for (const { type, subType } of entries) {
|
|
39
39
|
if (eventConfig.isCapOutboxEvent(type)) {
|
|
40
40
|
const [srvName, actionName] = subType.split(".");
|
|
41
|
-
|
|
42
|
-
.to(srvName)
|
|
43
|
-
|
|
44
|
-
if (!filterAppSpecificEvents) {
|
|
45
|
-
return; // will be done in finally
|
|
46
|
-
}
|
|
47
|
-
|
|
41
|
+
try {
|
|
42
|
+
const service = await cds.connect.to(srvName);
|
|
43
|
+
if (filterAppSpecificEvents) {
|
|
48
44
|
if (!service) {
|
|
49
|
-
|
|
45
|
+
continue;
|
|
50
46
|
}
|
|
51
47
|
cds.outboxed(service);
|
|
52
48
|
if (actionName) {
|
|
53
49
|
config.addCAPOutboxEventSpecificAction(srvName, actionName);
|
|
54
50
|
}
|
|
55
|
-
if (
|
|
56
|
-
if (eventConfig.shouldBeProcessedInThisApplication(type, subType)) {
|
|
57
|
-
result.push({ type, subType });
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
result.push({ type, subType });
|
|
61
|
-
}
|
|
62
|
-
})
|
|
63
|
-
.catch(() => {})
|
|
64
|
-
.finally(() => {
|
|
65
|
-
if (!filterAppSpecificEvents) {
|
|
51
|
+
if (eventConfig.shouldBeProcessedInThisApplication(type, subType)) {
|
|
66
52
|
result.push({ type, subType });
|
|
67
53
|
}
|
|
68
|
-
}
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
/* ignore catch */
|
|
57
|
+
} finally {
|
|
58
|
+
if (!filterAppSpecificEvents) {
|
|
59
|
+
result.push({ type, subType });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
69
62
|
} else {
|
|
70
63
|
if (filterAppSpecificEvents) {
|
|
71
64
|
if (
|
package/src/shared/cdsHelper.js
CHANGED
|
@@ -150,7 +150,9 @@ const getAllTenantIds = async () => {
|
|
|
150
150
|
}, []);
|
|
151
151
|
};
|
|
152
152
|
|
|
153
|
-
const
|
|
153
|
+
const TENANT_COLUMNS = ["subscribedSubdomain", "createdAt", "modifiedAt"];
|
|
154
|
+
|
|
155
|
+
const getAllTenantWithMetadata = async () => {
|
|
154
156
|
const response = await _getAllTenantBase();
|
|
155
157
|
if (!response) {
|
|
156
158
|
return null;
|
|
@@ -160,10 +162,19 @@ const getAllTenantWithSubdomain = async () => {
|
|
|
160
162
|
const tenantId = row.subscribedTenantId ?? row.tenant;
|
|
161
163
|
result = await result;
|
|
162
164
|
if (await common.isTenantIdValidCb(TenantIdCheckTypes.eventProcessing, tenantId)) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
const data = Object.entries(row).reduce(
|
|
166
|
+
(result, [key, value]) => {
|
|
167
|
+
if (TENANT_COLUMNS.includes(key)) {
|
|
168
|
+
result[key] = value;
|
|
169
|
+
} else {
|
|
170
|
+
result.metadata[key] = value;
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
173
|
+
},
|
|
174
|
+
{ metadata: {} }
|
|
175
|
+
);
|
|
176
|
+
data.metadata = JSON.stringify(data.metadata);
|
|
177
|
+
result.push(data);
|
|
167
178
|
}
|
|
168
179
|
return result;
|
|
169
180
|
}, []);
|
|
@@ -172,5 +183,5 @@ const getAllTenantWithSubdomain = async () => {
|
|
|
172
183
|
module.exports = {
|
|
173
184
|
executeInNewTransaction,
|
|
174
185
|
getAllTenantIds,
|
|
175
|
-
|
|
186
|
+
getAllTenantWithMetadata,
|
|
176
187
|
};
|
|
@@ -121,8 +121,9 @@ const _checkLockExistsDb = async (context, fullKey) => {
|
|
|
121
121
|
|
|
122
122
|
const _releaseLockRedis = async (context, fullKey) => {
|
|
123
123
|
const client = await redis.createMainClientAndConnect(config.redisOptions);
|
|
124
|
-
await client.del(fullKey);
|
|
124
|
+
const result = await client.del(fullKey);
|
|
125
125
|
delete existingLocks[fullKey];
|
|
126
|
+
return result === 1;
|
|
126
127
|
};
|
|
127
128
|
|
|
128
129
|
const _releaseLockDb = async (context, fullKey) => {
|
|
@@ -130,6 +131,7 @@ const _releaseLockDb = async (context, fullKey) => {
|
|
|
130
131
|
await tx.run(DELETE.from(config.tableNameEventLock).where("code =", fullKey));
|
|
131
132
|
});
|
|
132
133
|
delete existingLocks[fullKey];
|
|
134
|
+
return true;
|
|
133
135
|
};
|
|
134
136
|
|
|
135
137
|
const _acquireLockDB = async (
|
|
@@ -13,14 +13,14 @@ service EventQueueAdminService {
|
|
|
13
13
|
null as space: String,
|
|
14
14
|
*
|
|
15
15
|
} actions {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
action setStatusAndAttempts(
|
|
17
|
+
// TODO: remove tenant as soon as CAP issue is fixed https://github.tools.sap/cap/issues/issues/18445
|
|
18
|
+
@mandatory
|
|
19
|
+
tenant: String,
|
|
20
|
+
status: db.Status,
|
|
21
|
+
@assert.range: [0,100]
|
|
22
|
+
attempts: Integer) returns Event;
|
|
23
|
+
}
|
|
24
24
|
|
|
25
25
|
@cds.persistence.skip
|
|
26
26
|
@readonly
|
|
@@ -32,12 +32,22 @@ service EventQueueAdminService {
|
|
|
32
32
|
space: String;
|
|
33
33
|
ttl: Integer;
|
|
34
34
|
createdAt: Integer;
|
|
35
|
-
}
|
|
35
|
+
} actions {
|
|
36
|
+
action releaseLock(
|
|
37
|
+
// TODO: remove tenant as soon as CAP issue is fixed https://github.tools.sap/cap/issues/issues/18445
|
|
38
|
+
@mandatory
|
|
39
|
+
tenant: String,
|
|
40
|
+
@mandatory
|
|
41
|
+
type: String,
|
|
42
|
+
@mandatory
|
|
43
|
+
subType: String) returns Boolean;
|
|
44
|
+
}
|
|
36
45
|
|
|
37
46
|
@readonly
|
|
38
47
|
@cds.persistence.skip
|
|
39
48
|
entity Tenant {
|
|
40
49
|
Key ID: String;
|
|
41
50
|
subdomain: String;
|
|
51
|
+
metadata: String;
|
|
42
52
|
}
|
|
43
53
|
}
|
|
@@ -5,6 +5,7 @@ const cdsHelper = require("../../src/shared/cdsHelper");
|
|
|
5
5
|
const { EventProcessingStatus } = require("../../src");
|
|
6
6
|
const config = require("../../src/config");
|
|
7
7
|
const distributedLock = require("../../src/shared/distributedLock");
|
|
8
|
+
const redisPub = require("../../src/redis/redisPub");
|
|
8
9
|
|
|
9
10
|
module.exports = class AdminService extends cds.ApplicationService {
|
|
10
11
|
async init() {
|
|
@@ -61,7 +62,7 @@ module.exports = class AdminService extends cds.ApplicationService {
|
|
|
61
62
|
});
|
|
62
63
|
|
|
63
64
|
this.on("READ", Tenant, async () => {
|
|
64
|
-
const tenants = await cdsHelper.
|
|
65
|
+
const tenants = await cdsHelper.getAllTenantWithMetadata();
|
|
65
66
|
return tenants ?? [];
|
|
66
67
|
});
|
|
67
68
|
|
|
@@ -82,14 +83,27 @@ module.exports = class AdminService extends cds.ApplicationService {
|
|
|
82
83
|
return req.reject(400, "No status or attempts provided");
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
await cds.tx({ tenant, headers: { "z-id": tenant } }, async () => {
|
|
86
|
+
const event = await cds.tx({ tenant, headers: { "z-id": tenant } }, async () => {
|
|
87
|
+
const event = await SELECT.one.from(EventDb).where({ ID: req.params[0].ID ?? req.params[0] });
|
|
86
88
|
await UPDATE.entity(EventDb)
|
|
87
89
|
.set(updateData)
|
|
88
90
|
.where({ ID: req.params[0].ID ?? req.params[0] });
|
|
91
|
+
return event;
|
|
92
|
+
});
|
|
93
|
+
redisPub.broadcastEvent(tenant, event).catch(() => {
|
|
94
|
+
/* ignore errors */
|
|
89
95
|
});
|
|
90
96
|
return await this.send(new cds.Request({ query: req.query, headers: req.headers }));
|
|
91
97
|
});
|
|
92
98
|
|
|
99
|
+
this.on("releaseLock", async (req) => {
|
|
100
|
+
cds.log("eventQueue").info("Releasing event-queue lock", req.data);
|
|
101
|
+
const { tenant, type, subType } = req.data;
|
|
102
|
+
return await cds.tx({ tenant }, async (tx) => {
|
|
103
|
+
return await distributedLock.releaseLock(tx.context, [type, subType].join("##"));
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
93
107
|
await super.init();
|
|
94
108
|
}
|
|
95
109
|
|