@nocobase/server 1.9.0-beta.6 → 1.9.0-beta.8
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/lib/event-queue.d.ts +2 -0
- package/lib/event-queue.js +24 -20
- package/package.json +15 -15
package/lib/event-queue.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import Application from './application';
|
|
10
|
+
import { SystemLogger } from '@nocobase/logger';
|
|
10
11
|
export declare const QUEUE_DEFAULT_INTERVAL = 250;
|
|
11
12
|
export declare const QUEUE_DEFAULT_CONCURRENCY = 1;
|
|
12
13
|
export declare const QUEUE_DEFAULT_ACK_TIMEOUT = 15000;
|
|
@@ -58,6 +59,7 @@ export declare class MemoryEventQueueAdapter implements IEventQueueAdapter {
|
|
|
58
59
|
listen: (channel: string) => void;
|
|
59
60
|
constructor(options: {
|
|
60
61
|
appName: string;
|
|
62
|
+
logger: SystemLogger;
|
|
61
63
|
});
|
|
62
64
|
isConnected(): boolean;
|
|
63
65
|
setConnected(connected: boolean): void;
|
package/lib/event-queue.js
CHANGED
|
@@ -77,9 +77,10 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
77
77
|
if (!this.connected) {
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
|
+
const { logger } = this.options;
|
|
80
81
|
const event = this.events.get(channel);
|
|
81
82
|
if (!event) {
|
|
82
|
-
|
|
83
|
+
logger.warn(`memory queue (${channel}) not found, skipping...`);
|
|
83
84
|
return;
|
|
84
85
|
}
|
|
85
86
|
if (!event.idle()) {
|
|
@@ -88,12 +89,9 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
88
89
|
const reading = this.reading.get(channel) || [];
|
|
89
90
|
const count = (event.concurrency || QUEUE_DEFAULT_CONCURRENCY) - reading.length;
|
|
90
91
|
if (count <= 0) {
|
|
91
|
-
console.debug(
|
|
92
|
-
`memory queue (${channel}) is already reading as max concurrency (${reading.length}), waiting last reading to end...`
|
|
93
|
-
);
|
|
94
92
|
return;
|
|
95
93
|
}
|
|
96
|
-
|
|
94
|
+
logger.debug(`reading more from queue (${channel}), count: ${count}`);
|
|
97
95
|
this.read(channel, count).forEach((promise) => {
|
|
98
96
|
reading.push(promise);
|
|
99
97
|
promise.finally(() => {
|
|
@@ -114,20 +112,21 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
114
112
|
async loadFromStorage() {
|
|
115
113
|
let queues = {};
|
|
116
114
|
let exists = false;
|
|
115
|
+
const { logger } = this.options;
|
|
117
116
|
try {
|
|
118
117
|
await import_promises.default.stat(this.storagePath);
|
|
119
118
|
exists = true;
|
|
120
119
|
} catch (ex) {
|
|
121
|
-
|
|
120
|
+
logger.info(`memory queue storage file not found, skip`);
|
|
122
121
|
}
|
|
123
122
|
if (exists) {
|
|
124
123
|
try {
|
|
125
124
|
const queueJson = await import_promises.default.readFile(this.storagePath);
|
|
126
125
|
queues = JSON.parse(queueJson.toString());
|
|
127
|
-
|
|
126
|
+
logger.debug("memory queue loaded from storage", queues);
|
|
128
127
|
await import_promises.default.unlink(this.storagePath);
|
|
129
128
|
} catch (ex) {
|
|
130
|
-
|
|
129
|
+
logger.error("failed to load queue from storage", ex);
|
|
131
130
|
}
|
|
132
131
|
}
|
|
133
132
|
this.queues = new Map(Object.entries(queues));
|
|
@@ -139,12 +138,13 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
139
138
|
}
|
|
140
139
|
return acc;
|
|
141
140
|
}, {});
|
|
141
|
+
const { logger } = this.options;
|
|
142
142
|
if (Object.keys(queues).length) {
|
|
143
143
|
await import_promises.default.mkdir(import_path.default.dirname(this.storagePath), { recursive: true });
|
|
144
144
|
await import_promises.default.writeFile(this.storagePath, JSON.stringify(queues));
|
|
145
|
-
|
|
145
|
+
logger.debug("memory queue saved to storage", queues);
|
|
146
146
|
} else {
|
|
147
|
-
|
|
147
|
+
logger.debug("memory queue empty, no need to save to storage");
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
async connect() {
|
|
@@ -163,13 +163,14 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
163
163
|
if (!this.connected) {
|
|
164
164
|
return;
|
|
165
165
|
}
|
|
166
|
+
const { logger } = this.options;
|
|
166
167
|
this.connected = false;
|
|
167
168
|
if (this.processing) {
|
|
168
|
-
|
|
169
|
+
logger.info("memory queue waiting for processing job...");
|
|
169
170
|
await this.processing;
|
|
170
|
-
|
|
171
|
+
logger.info("memory queue job cleaned");
|
|
171
172
|
}
|
|
172
|
-
|
|
173
|
+
logger.info("memory queue gracefully shutting down...");
|
|
173
174
|
await this.saveToStorage();
|
|
174
175
|
}
|
|
175
176
|
subscribe(channel, options) {
|
|
@@ -204,7 +205,8 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
204
205
|
const queue = this.queues.get(channel);
|
|
205
206
|
const message = { id: (0, import_crypto.randomUUID)(), content, options };
|
|
206
207
|
queue.push(message);
|
|
207
|
-
|
|
208
|
+
const { logger } = this.options;
|
|
209
|
+
logger.debug(`memory queue (${channel}) published message`, content);
|
|
208
210
|
setImmediate(() => {
|
|
209
211
|
this.emitter.emit(channel, channel);
|
|
210
212
|
});
|
|
@@ -228,8 +230,9 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
228
230
|
if (!(queue == null ? void 0 : queue.length)) {
|
|
229
231
|
return [];
|
|
230
232
|
}
|
|
233
|
+
const { logger } = this.options;
|
|
231
234
|
const messages = queue.slice(0, n);
|
|
232
|
-
|
|
235
|
+
logger.debug(`memory queue (${channel}) read ${messages.length} messages`, messages);
|
|
233
236
|
queue.splice(0, messages.length);
|
|
234
237
|
const batch = messages.map(({ id, ...message }) => this.process(channel, { id, message }));
|
|
235
238
|
return batch;
|
|
@@ -237,17 +240,18 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
237
240
|
async process(channel, { id, message }) {
|
|
238
241
|
const event = this.events.get(channel);
|
|
239
242
|
const { content, options: { timeout = QUEUE_DEFAULT_ACK_TIMEOUT, maxRetries = 0, retried = 0 } = {} } = message;
|
|
240
|
-
|
|
243
|
+
const { logger } = this.options;
|
|
244
|
+
logger.debug(`memory queue (${channel}) processing message (${id})...`, content);
|
|
241
245
|
return (async () => event.process(content, {
|
|
242
246
|
id,
|
|
243
247
|
retried,
|
|
244
248
|
signal: AbortSignal.timeout(timeout)
|
|
245
249
|
}))().then(() => {
|
|
246
|
-
|
|
250
|
+
logger.debug(`memory queue (${channel}) consumed message (${id})`);
|
|
247
251
|
}).catch((ex) => {
|
|
248
252
|
if (maxRetries > 0 && retried < maxRetries) {
|
|
249
253
|
const currentRetry = retried + 1;
|
|
250
|
-
|
|
254
|
+
logger.warn(
|
|
251
255
|
`memory queue (${channel}) consum message (${id}) failed, retrying (${currentRetry} / ${maxRetries})...`,
|
|
252
256
|
ex
|
|
253
257
|
);
|
|
@@ -255,7 +259,7 @@ const _MemoryEventQueueAdapter = class _MemoryEventQueueAdapter {
|
|
|
255
259
|
this.publish(channel, content, { timeout, maxRetries, retried: currentRetry, timestamp: Date.now() });
|
|
256
260
|
}, 500);
|
|
257
261
|
} else {
|
|
258
|
-
|
|
262
|
+
logger.error(ex);
|
|
259
263
|
}
|
|
260
264
|
});
|
|
261
265
|
}
|
|
@@ -267,7 +271,7 @@ const _EventQueue = class _EventQueue {
|
|
|
267
271
|
this.app = app;
|
|
268
272
|
this.options = options;
|
|
269
273
|
if (app.serving()) {
|
|
270
|
-
this.setAdapter(new MemoryEventQueueAdapter({ appName: this.app.name }));
|
|
274
|
+
this.setAdapter(new MemoryEventQueueAdapter({ appName: this.app.name, logger: this.app.logger }));
|
|
271
275
|
app.on("afterStart", async () => {
|
|
272
276
|
await this.connect();
|
|
273
277
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/server",
|
|
3
|
-
"version": "1.9.0-beta.
|
|
3
|
+
"version": "1.9.0-beta.8",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "./lib/index.d.ts",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -10,19 +10,19 @@
|
|
|
10
10
|
"@koa/cors": "^5.0.0",
|
|
11
11
|
"@koa/multer": "^3.1.0",
|
|
12
12
|
"@koa/router": "^13.1.0",
|
|
13
|
-
"@nocobase/acl": "1.9.0-beta.
|
|
14
|
-
"@nocobase/actions": "1.9.0-beta.
|
|
15
|
-
"@nocobase/auth": "1.9.0-beta.
|
|
16
|
-
"@nocobase/cache": "1.9.0-beta.
|
|
17
|
-
"@nocobase/data-source-manager": "1.9.0-beta.
|
|
18
|
-
"@nocobase/database": "1.9.0-beta.
|
|
19
|
-
"@nocobase/evaluators": "1.9.0-beta.
|
|
20
|
-
"@nocobase/lock-manager": "1.9.0-beta.
|
|
21
|
-
"@nocobase/logger": "1.9.0-beta.
|
|
22
|
-
"@nocobase/resourcer": "1.9.0-beta.
|
|
23
|
-
"@nocobase/sdk": "1.9.0-beta.
|
|
24
|
-
"@nocobase/telemetry": "1.9.0-beta.
|
|
25
|
-
"@nocobase/utils": "1.9.0-beta.
|
|
13
|
+
"@nocobase/acl": "1.9.0-beta.8",
|
|
14
|
+
"@nocobase/actions": "1.9.0-beta.8",
|
|
15
|
+
"@nocobase/auth": "1.9.0-beta.8",
|
|
16
|
+
"@nocobase/cache": "1.9.0-beta.8",
|
|
17
|
+
"@nocobase/data-source-manager": "1.9.0-beta.8",
|
|
18
|
+
"@nocobase/database": "1.9.0-beta.8",
|
|
19
|
+
"@nocobase/evaluators": "1.9.0-beta.8",
|
|
20
|
+
"@nocobase/lock-manager": "1.9.0-beta.8",
|
|
21
|
+
"@nocobase/logger": "1.9.0-beta.8",
|
|
22
|
+
"@nocobase/resourcer": "1.9.0-beta.8",
|
|
23
|
+
"@nocobase/sdk": "1.9.0-beta.8",
|
|
24
|
+
"@nocobase/telemetry": "1.9.0-beta.8",
|
|
25
|
+
"@nocobase/utils": "1.9.0-beta.8",
|
|
26
26
|
"@types/decompress": "4.2.7",
|
|
27
27
|
"@types/ini": "^1.3.31",
|
|
28
28
|
"@types/koa-send": "^4.1.3",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"@types/serve-handler": "^6.1.1",
|
|
58
58
|
"@types/ws": "^8.5.5"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "f3d4f3d1ba7adbf4d4c60e656c23da45565769c8"
|
|
61
61
|
}
|