@cap-js-community/event-queue 1.10.0-beta.2 → 1.10.0-beta.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.0-beta.
|
|
3
|
+
"version": "1.10.0-beta.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",
|
|
@@ -57,21 +57,29 @@ class EventQueueGenericOutboxHandler extends EventQueueBaseClass {
|
|
|
57
57
|
return super.clusterQueueEntries(queueEntriesWithPayloadMap);
|
|
58
58
|
}
|
|
59
59
|
const { genericClusterEvents, specificClusterEvents } = this.#clusterByAction(queueEntriesWithPayloadMap);
|
|
60
|
+
|
|
60
61
|
if (Object.keys(genericClusterEvents).length) {
|
|
61
62
|
if (!this.__genericClusterRelevantAndAvailable) {
|
|
62
|
-
|
|
63
|
+
for (const actionName in genericClusterEvents) {
|
|
64
|
+
await super.clusterQueueEntries(genericClusterEvents[actionName]);
|
|
65
|
+
}
|
|
63
66
|
} else {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
67
|
+
for (const actionName in genericClusterEvents) {
|
|
68
|
+
const msg = new cds.Request({
|
|
69
|
+
event: `clusterQueueEntries`,
|
|
70
|
+
eventQueue: {
|
|
71
|
+
processor: this,
|
|
72
|
+
clusterByPayloadProperty: (propertyName, cb) =>
|
|
73
|
+
this.clusterByPayloadProperty(actionName, genericClusterEvents[actionName], propertyName, cb),
|
|
74
|
+
clusterByEventProperty: (propertyName, cb) =>
|
|
75
|
+
this.clusterByEventProperty(actionName, genericClusterEvents[actionName], propertyName, cb),
|
|
76
|
+
clusterByDataProperty: (propertyName, cb) =>
|
|
77
|
+
this.clusterByDataProperty(actionName, specificClusterEvents[actionName], propertyName, cb),
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
const handlerCluster = await this.__srvUnboxed.tx(this.context).send(msg);
|
|
81
|
+
this.#addToProcessingMap(handlerCluster);
|
|
82
|
+
}
|
|
75
83
|
}
|
|
76
84
|
}
|
|
77
85
|
|
|
@@ -81,9 +89,11 @@ class EventQueueGenericOutboxHandler extends EventQueueBaseClass {
|
|
|
81
89
|
eventQueue: {
|
|
82
90
|
processor: this,
|
|
83
91
|
clusterByPayloadProperty: (propertyName, cb) =>
|
|
84
|
-
this.clusterByPayloadProperty(specificClusterEvents[actionName], propertyName, cb),
|
|
92
|
+
this.clusterByPayloadProperty(actionName, specificClusterEvents[actionName], propertyName, cb),
|
|
85
93
|
clusterByEventProperty: (propertyName, cb) =>
|
|
86
|
-
this.clusterByEventProperty(specificClusterEvents[actionName], propertyName, cb),
|
|
94
|
+
this.clusterByEventProperty(actionName, specificClusterEvents[actionName], propertyName, cb),
|
|
95
|
+
clusterByDataProperty: (propertyName, cb) =>
|
|
96
|
+
this.clusterByDataProperty(actionName, specificClusterEvents[actionName], propertyName, cb),
|
|
87
97
|
},
|
|
88
98
|
});
|
|
89
99
|
const handlerCluster = await this.__srvUnboxed.tx(this.context).send(msg);
|
|
@@ -92,55 +102,66 @@ class EventQueueGenericOutboxHandler extends EventQueueBaseClass {
|
|
|
92
102
|
}
|
|
93
103
|
|
|
94
104
|
clusterBase(queueEntriesWithPayloadMap, propertyName, refCb, cb) {
|
|
95
|
-
|
|
105
|
+
const clusters = Object.entries(queueEntriesWithPayloadMap).reduce((result, [, { queueEntry, payload }]) => {
|
|
96
106
|
const ref = refCb(result, payload, queueEntry);
|
|
97
107
|
ref.queueEntries.push(queueEntry);
|
|
98
|
-
if (cb) {
|
|
99
|
-
const clusterResult = cb(ref.payload.data, queueEntry.payload.data, index);
|
|
100
|
-
ref.payload.data ??= clusterResult;
|
|
101
|
-
}
|
|
102
108
|
return result;
|
|
103
109
|
}, {});
|
|
110
|
+
|
|
111
|
+
if (cb) {
|
|
112
|
+
for (const clustersKey in clusters) {
|
|
113
|
+
const clusterData = clusters[clustersKey];
|
|
114
|
+
const clusterResult = cb(
|
|
115
|
+
clustersKey.split("##").shift(),
|
|
116
|
+
clusterData.queueEntries.map((entry) => entry.payload.data)
|
|
117
|
+
);
|
|
118
|
+
if (!clusterResult) {
|
|
119
|
+
throw new Error("hmm??");
|
|
120
|
+
}
|
|
121
|
+
clusterData.payload.data = clusterResult;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return clusters;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
#resolveRefBase(result, propertyName, actionName, payload, startRef) {
|
|
128
|
+
const parts = propertyName.split(".");
|
|
129
|
+
const data = JSON.parse(JSON.stringify(payload.data));
|
|
130
|
+
let ref = startRef;
|
|
131
|
+
for (const part of parts) {
|
|
132
|
+
ref = ref[part];
|
|
133
|
+
}
|
|
134
|
+
const key = [actionName, ref].join("##");
|
|
135
|
+
result[key] ??= {
|
|
136
|
+
queueEntries: [],
|
|
137
|
+
payload: { ...payload, data },
|
|
138
|
+
};
|
|
139
|
+
return result[key];
|
|
104
140
|
}
|
|
105
141
|
|
|
106
|
-
clusterByPayloadProperty(queueEntriesWithPayloadMap, propertyName, cb) {
|
|
142
|
+
clusterByPayloadProperty(actionName, queueEntriesWithPayloadMap, propertyName, cb) {
|
|
107
143
|
return this.clusterBase(
|
|
108
144
|
queueEntriesWithPayloadMap,
|
|
109
145
|
propertyName,
|
|
110
|
-
(result, payload) =>
|
|
111
|
-
const parts = propertyName.split(".");
|
|
112
|
-
const data = JSON.parse(JSON.stringify(payload.data));
|
|
113
|
-
let ref = payload;
|
|
114
|
-
for (const part of parts) {
|
|
115
|
-
ref = ref[part];
|
|
116
|
-
}
|
|
117
|
-
result[ref[propertyName]] ??= {
|
|
118
|
-
queueEntries: [],
|
|
119
|
-
payload: { ...payload, data },
|
|
120
|
-
};
|
|
121
|
-
return result[ref[propertyName]];
|
|
122
|
-
},
|
|
146
|
+
(result, payload) => this.#resolveRefBase(result, propertyName, actionName, payload, payload),
|
|
123
147
|
cb
|
|
124
148
|
);
|
|
125
149
|
}
|
|
126
150
|
|
|
127
|
-
clusterByEventProperty(queueEntriesWithPayloadMap, propertyName, cb) {
|
|
151
|
+
clusterByEventProperty(actionName, queueEntriesWithPayloadMap, propertyName, cb) {
|
|
128
152
|
return this.clusterBase(
|
|
129
153
|
queueEntriesWithPayloadMap,
|
|
130
154
|
propertyName,
|
|
131
|
-
(result, payload, queueEntry) =>
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
};
|
|
142
|
-
return result[queueEntry[propertyName]];
|
|
143
|
-
},
|
|
155
|
+
(result, payload, queueEntry) => this.#resolveRefBase(result, propertyName, actionName, payload, queueEntry),
|
|
156
|
+
cb
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
clusterByDataProperty(actionName, queueEntriesWithPayloadMap, propertyName, cb) {
|
|
161
|
+
return this.clusterBase(
|
|
162
|
+
queueEntriesWithPayloadMap,
|
|
163
|
+
propertyName,
|
|
164
|
+
(result, payload) => this.#resolveRefBase(result, propertyName, actionName, payload, payload.data),
|
|
144
165
|
cb
|
|
145
166
|
);
|
|
146
167
|
}
|
|
@@ -153,7 +174,8 @@ class EventQueueGenericOutboxHandler extends EventQueueBaseClass {
|
|
|
153
174
|
result.specificClusterEvents[clusterData.payload.event] ??= {};
|
|
154
175
|
result.specificClusterEvents[clusterData.payload.event][eventId] = clusterData;
|
|
155
176
|
} else {
|
|
156
|
-
result.genericClusterEvents[
|
|
177
|
+
result.genericClusterEvents[clusterData.payload.event] ??= {};
|
|
178
|
+
result.genericClusterEvents[clusterData.payload.event][eventId] = clusterData;
|
|
157
179
|
}
|
|
158
180
|
return result;
|
|
159
181
|
},
|
|
@@ -198,7 +220,7 @@ class EventQueueGenericOutboxHandler extends EventQueueBaseClass {
|
|
|
198
220
|
queueEntries: [queueEntry],
|
|
199
221
|
});
|
|
200
222
|
msg.event = handlerName;
|
|
201
|
-
await this.#setContextUser(this.context, userId);
|
|
223
|
+
await this.#setContextUser(this.context, userId, msg);
|
|
202
224
|
const data = await this.__srvUnboxed.tx(this.context).send(msg);
|
|
203
225
|
if (data) {
|
|
204
226
|
payload.data = data;
|
|
@@ -233,7 +255,7 @@ class EventQueueGenericOutboxHandler extends EventQueueBaseClass {
|
|
|
233
255
|
async processPeriodicEvent(processContext, key, queueEntry) {
|
|
234
256
|
const [, action] = this.eventSubType.split(".");
|
|
235
257
|
const msg = new cds.Event({ event: action, eventQueue: { processor: this, key, queueEntries: [queueEntry] } });
|
|
236
|
-
await this.#setContextUser(processContext, config.userId);
|
|
258
|
+
await this.#setContextUser(processContext, config.userId, msg);
|
|
237
259
|
await this.__srvUnboxed.tx(processContext).emit(msg);
|
|
238
260
|
}
|
|
239
261
|
|
|
@@ -248,17 +270,20 @@ class EventQueueGenericOutboxHandler extends EventQueueBaseClass {
|
|
|
248
270
|
return { msg, userId, invocationFn };
|
|
249
271
|
}
|
|
250
272
|
|
|
251
|
-
async #setContextUser(context, userId) {
|
|
273
|
+
async #setContextUser(context, userId, data) {
|
|
252
274
|
context.user = new cds.User.Privileged({
|
|
253
275
|
id: userId,
|
|
254
276
|
authInfo: await common.getTokenInfo(this.baseContext.tenant),
|
|
255
277
|
});
|
|
278
|
+
if (data) {
|
|
279
|
+
data.user = context.user;
|
|
280
|
+
}
|
|
256
281
|
}
|
|
257
282
|
|
|
258
283
|
async processEvent(processContext, key, queueEntries, payload) {
|
|
259
284
|
try {
|
|
260
285
|
const { userId, invocationFn, msg } = this.#buildDispatchData(processContext, payload, { key, queueEntries });
|
|
261
|
-
await this.#setContextUser(processContext, userId);
|
|
286
|
+
await this.#setContextUser(processContext, userId, msg);
|
|
262
287
|
const result = await this.__srvUnboxed.tx(processContext)[invocationFn](msg);
|
|
263
288
|
return this.#determineResultStatus(result, queueEntries);
|
|
264
289
|
} catch (err) {
|