@yolo-croket-dev/core 1.4.53-slowquery.6 → 1.4.53-slowquery.7
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.
|
@@ -266,7 +266,6 @@ let RPCInterceptor = class RPCInterceptor {
|
|
|
266
266
|
else {
|
|
267
267
|
// logger.debug(`=> (${traceId}): ${JSON.stringify(this.keyCutter(JSON.stringify(content)))}`);
|
|
268
268
|
}
|
|
269
|
-
msaLogger.debug('RPCInterceptor IncActiveInterceptors called', { traceId: 'INC_RPC_ACTIVE_INTERCEPTORS' });
|
|
270
269
|
this.gracefulShutdownService.incActiveInterceptors();
|
|
271
270
|
// eslint-disable-next-line consistent-return
|
|
272
271
|
return next
|
|
@@ -292,7 +291,6 @@ let RPCInterceptor = class RPCInterceptor {
|
|
|
292
291
|
},
|
|
293
292
|
error: localErrorProcessor,
|
|
294
293
|
}), (0, operators_1.finalize)(() => {
|
|
295
|
-
msaLogger.debug('RPCInterceptor DecActiveInterceptors called', { traceId: 'DEC_RPC_ACTIVE_INTERCEPTORS' });
|
|
296
294
|
this.gracefulShutdownService.decActiveInterceptors();
|
|
297
295
|
}));
|
|
298
296
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RmqOptions, ServerRMQ } from '@nestjs/microservices';
|
|
2
|
+
import { Channel } from 'amqp-connection-manager';
|
|
3
|
+
import { ConsumeMessage } from 'amqplib';
|
|
4
|
+
export type GracefulRmqOptions = RmqOptions['options'] & {
|
|
5
|
+
waitingEndingHandlersTimeoutMs?: number;
|
|
6
|
+
waitingEndingHandlersIntervalMs?: number;
|
|
7
|
+
};
|
|
8
|
+
export declare class GracefulServerRMQ extends ServerRMQ {
|
|
9
|
+
protected readonly options: GracefulRmqOptions;
|
|
10
|
+
protected runningMessages: number;
|
|
11
|
+
protected closing: boolean;
|
|
12
|
+
protected consumerTag: string | null;
|
|
13
|
+
protected readonly waitingEndingHandlersTimeoutMs: number;
|
|
14
|
+
protected readonly waitingEndingHandlersIntervalMs: number;
|
|
15
|
+
constructor(options: GracefulRmqOptions);
|
|
16
|
+
setupChannel(channel: Channel, callback: () => void): Promise<void>;
|
|
17
|
+
protected waitingHandlers(): Promise<void>;
|
|
18
|
+
handleMessage(message: ConsumeMessage, channel: Channel): Promise<void>;
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GracefulServerRMQ = void 0;
|
|
4
|
+
const microservices_1 = require("@nestjs/microservices");
|
|
5
|
+
const node_util_1 = require("node:util");
|
|
6
|
+
const sleep = (0, node_util_1.promisify)(setTimeout);
|
|
7
|
+
const RMQ_DEFAULT_WAITING_ENDING_HANDLERS_TIMEOUT_MS = 5000;
|
|
8
|
+
const RMQ_DEFAULT_WAITING_ENDING_HANDLERS_INTERVAL_MS = 500;
|
|
9
|
+
class GracefulServerRMQ extends microservices_1.ServerRMQ {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
super(options);
|
|
12
|
+
this.options = options;
|
|
13
|
+
this.runningMessages = 0;
|
|
14
|
+
this.closing = false;
|
|
15
|
+
this.consumerTag = null;
|
|
16
|
+
this.waitingEndingHandlersTimeoutMs = this.getOptionsProp(this.options, 'waitingEndingHandlersTimeoutMs')
|
|
17
|
+
|| RMQ_DEFAULT_WAITING_ENDING_HANDLERS_TIMEOUT_MS;
|
|
18
|
+
this.waitingEndingHandlersIntervalMs = this.getOptionsProp(this.options, 'waitingEndingHandlersIntervalMs')
|
|
19
|
+
|| RMQ_DEFAULT_WAITING_ENDING_HANDLERS_INTERVAL_MS;
|
|
20
|
+
}
|
|
21
|
+
async setupChannel(channel, callback) {
|
|
22
|
+
if (this.closing) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!this.queueOptions.noAssert) {
|
|
26
|
+
await channel.assertQueue(this.queue, this.queueOptions);
|
|
27
|
+
}
|
|
28
|
+
await channel.prefetch(this.prefetchCount, this.isGlobalPrefetchCount);
|
|
29
|
+
const { consumerTag } = await channel.consume(this.queue, (msg) => this.handleMessage(msg, channel), { noAck: false });
|
|
30
|
+
this.consumerTag = consumerTag;
|
|
31
|
+
callback();
|
|
32
|
+
}
|
|
33
|
+
async waitingHandlers() {
|
|
34
|
+
while (this.runningMessages > 0) {
|
|
35
|
+
await sleep(this.waitingEndingHandlersIntervalMs);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async handleMessage(message, channel) {
|
|
39
|
+
this.runningMessages += 1;
|
|
40
|
+
return super.handleMessage(message, channel).finally(() => {
|
|
41
|
+
this.runningMessages -= 1;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async close() {
|
|
45
|
+
this.closing = true;
|
|
46
|
+
if (this.channel) {
|
|
47
|
+
await this.channel.removeSetup(undefined, (channel) => channel.cancel(this.consumerTag));
|
|
48
|
+
}
|
|
49
|
+
this.consumerTag = null;
|
|
50
|
+
await Promise.race([
|
|
51
|
+
this.waitingHandlers(),
|
|
52
|
+
this.waitingEndingHandlersTimeoutMs > 0
|
|
53
|
+
&& sleep(this.waitingEndingHandlersTimeoutMs),
|
|
54
|
+
]);
|
|
55
|
+
this.runningMessages = 0;
|
|
56
|
+
super.close();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.GracefulServerRMQ = GracefulServerRMQ;
|
|
@@ -39,12 +39,10 @@ let GracefulShutdownService = class GracefulShutdownService {
|
|
|
39
39
|
this.isApplicationExit = false;
|
|
40
40
|
}
|
|
41
41
|
onApplicationBootstrap() {
|
|
42
|
-
msaLogger.debug('GracefulShutdownService.onApplicationBootstrap', { traceId: 'ON_APPLICATION_BOOTSTRAP' });
|
|
43
42
|
this.activeInterceptors = 0;
|
|
44
43
|
}
|
|
45
44
|
incActiveInterceptors() {
|
|
46
45
|
this.activeInterceptors += 1;
|
|
47
|
-
msaLogger.debug(`GracefulShutdownService.incActiveInterceptors: ${this.activeInterceptors}`, { traceId: 'INC_ACTIVE_INTERCEPTORS' });
|
|
48
46
|
}
|
|
49
47
|
decActiveInterceptors() {
|
|
50
48
|
this.activeInterceptors -= 1;
|
|
@@ -58,9 +56,13 @@ let GracefulShutdownService = class GracefulShutdownService {
|
|
|
58
56
|
this.isApplicationExit = true;
|
|
59
57
|
msaLogger.debug('GracefulShutdownService.onModuleDestroy', { traceId: 'ON_MODULE_DESTROY' });
|
|
60
58
|
msaLogger.debug(`GracefulShutdownService.onModuleDestroy: activeInterceptors=${this.activeInterceptors}`, { traceId: 'ON_MODULE_DESTROY' });
|
|
59
|
+
let prevExecInterceptorCount = 0;
|
|
61
60
|
while (this.activeInterceptors > 0) {
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
if (prevExecInterceptorCount !== this.activeInterceptors) {
|
|
62
|
+
prevExecInterceptorCount = this.activeInterceptors;
|
|
63
|
+
// eslint-disable-next-line max-len
|
|
64
|
+
msaLogger.debug(`GracefulShutdownService.onModuleDestroy: waiting for ${this.activeInterceptors} interceptors to finish`, { traceId: 'ON_MODULE_DESTROY' });
|
|
65
|
+
}
|
|
64
66
|
await new Promise((resolve) => {
|
|
65
67
|
setTimeout(resolve, 1000);
|
|
66
68
|
});
|