@yolo-croket-dev/core 1.4.53-slowquery.0 → 1.4.53-slowquery.10

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.
@@ -1,7 +1,7 @@
1
1
  import { ExecutionContext, NestInterceptor, CallHandler } from '@nestjs/common';
2
2
  import { Reflector } from '@nestjs/core';
3
3
  import { Observable } from 'rxjs';
4
- import { GracefulShutdownService } from '../services';
4
+ import { GracefulShutdownService } from '../modules/graceful-shutdown/graceful-shutdown.service';
5
5
  export declare class RPCInterceptor implements NestInterceptor {
6
6
  private readonly reflector;
7
7
  private readonly gracefulShutdownService;
@@ -1,10 +1,33 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
2
18
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
19
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
20
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
21
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
22
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
23
  };
24
+ var __importStar = (this && this.__importStar) || function (mod) {
25
+ if (mod && mod.__esModule) return mod;
26
+ var result = {};
27
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
+ __setModuleDefault(result, mod);
29
+ return result;
30
+ };
8
31
  var __metadata = (this && this.__metadata) || function (k, v) {
9
32
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
33
  };
@@ -15,10 +38,13 @@ const common_1 = require("@nestjs/common");
15
38
  const core_1 = require("@nestjs/core");
16
39
  const rxjs_1 = require("rxjs");
17
40
  const operators_1 = require("rxjs/operators");
41
+ const msa_logger_1 = __importStar(require("@yolo-croket-dev/msa-logger"));
18
42
  // import Logger from '@yolo-croket-dev/logger';
19
43
  const functions_1 = require("../functions");
20
44
  const exceptions_1 = require("../exceptions");
21
- const services_1 = require("../services");
45
+ const graceful_shutdown_service_1 = require("../modules/graceful-shutdown/graceful-shutdown.service");
46
+ // const logger = Logger.createLogger('RPCInterceptor');
47
+ const msaLogger = new msa_logger_1.default(msa_logger_1.ServerTypeEnum.SERVICE);
22
48
  // const MAX_CUT_LENGTH = 500;
23
49
  const MAX_LENGTH = 300;
24
50
  let RPCInterceptor = class RPCInterceptor {
@@ -108,7 +134,7 @@ let RPCInterceptor = class RPCInterceptor {
108
134
  // return data;
109
135
  // }
110
136
  async intercept(context, next) {
111
- var _a;
137
+ var _a, _b;
112
138
  const options = this.reflector.get('rpcInterceptorScope', context.getHandler());
113
139
  const args = context.getArgs();
114
140
  const arg = args[0];
@@ -120,13 +146,25 @@ let RPCInterceptor = class RPCInterceptor {
120
146
  // const traceId = content.data.param ? content.data.param.traceId : null;
121
147
  const isInternal = content.data.param ? content.data.param.isInternal : false;
122
148
  const isAdmin = content.data.param ? content.data.param.isAdmin : false;
123
- // const method = content.pattern;
124
149
  const reDeliveryCount = Number(message.properties.headers['x-delivery-count']) || 0; /** 몇번 재전달되었는지 */
125
150
  const staticRetryCount = Number(options === null || options === void 0 ? void 0 : options.messageRetryCount) || 0; /** 최대 재시도 갯수 */
151
+ const method = content.pattern;
152
+ const correlationId = message.properties.correlationId;
153
+ const execInterceptor = {
154
+ method,
155
+ traceId: ((_a = content.data.param) === null || _a === void 0 ? void 0 : _a.traceId) || '-',
156
+ correlationId,
157
+ };
126
158
  // const logParam = {
127
159
  // traceId,
128
160
  // method,
129
161
  // };
162
+ /** consume 메시지 전부 cancel */
163
+ if (this.gracefulShutdownService.isApplicationExit) {
164
+ msaLogger.debug('RPCInterceptor isApplicationExit called', { traceId: 'IS_APPLICATION_EXIT' });
165
+ channel.cancel(message.fields.consumerTag);
166
+ return new rxjs_1.Observable();
167
+ }
130
168
  if (!staticRetryCount && reDeliveryCount > 0) {
131
169
  channel.sendToQueue(message.properties.replyTo, Buffer.from(JSON.stringify({
132
170
  isError: true,
@@ -205,7 +243,7 @@ let RPCInterceptor = class RPCInterceptor {
205
243
  };
206
244
  localErrorProcessor = localErrorProcessor.bind(this);
207
245
  /** 파일 객체 처리 */
208
- (0, functions_1.reWriteFileValue)((_a = content === null || content === void 0 ? void 0 : content.data) === null || _a === void 0 ? void 0 : _a.file);
246
+ (0, functions_1.reWriteFileValue)((_b = content === null || content === void 0 ? void 0 : content.data) === null || _b === void 0 ? void 0 : _b.file);
209
247
  if (options) {
210
248
  if (options.maxLengthKeys && options.maxLengthKeys.length) {
211
249
  for (const key of options.maxLengthKeys) {
@@ -234,11 +272,12 @@ let RPCInterceptor = class RPCInterceptor {
234
272
  else {
235
273
  // logger.debug(`=> (${traceId}): ${JSON.stringify(this.keyCutter(JSON.stringify(content)))}`);
236
274
  }
237
- this.gracefulShutdownService.incActiveInterceptors();
275
+ this.gracefulShutdownService.pushActiveInterceptors(execInterceptor);
238
276
  // eslint-disable-next-line consistent-return
239
277
  return next
240
278
  .handle()
241
- .pipe((0, operators_1.tap)({
279
+ .pipe((0, operators_1.timeout)(1000 * 60 * 30), // 30분 타임아웃
280
+ (0, operators_1.tap)({
242
281
  next: async (val) => {
243
282
  val.isError = false;
244
283
  // const duration = Date.now() - now;
@@ -258,7 +297,7 @@ let RPCInterceptor = class RPCInterceptor {
258
297
  },
259
298
  error: localErrorProcessor,
260
299
  }), (0, operators_1.finalize)(() => {
261
- this.gracefulShutdownService.decActiveInterceptors();
300
+ this.gracefulShutdownService.popActiveInterceptors(execInterceptor);
262
301
  }));
263
302
  }
264
303
  };
@@ -266,5 +305,5 @@ exports.RPCInterceptor = RPCInterceptor;
266
305
  exports.RPCInterceptor = RPCInterceptor = __decorate([
267
306
  (0, common_1.Injectable)(),
268
307
  __metadata("design:paramtypes", [core_1.Reflector,
269
- services_1.GracefulShutdownService])
308
+ graceful_shutdown_service_1.GracefulShutdownService])
270
309
  ], RPCInterceptor);
@@ -0,0 +1,2 @@
1
+ export declare class GracefulShutdownModule {
2
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.GracefulShutdownModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const graceful_shutdown_service_1 = require("./graceful-shutdown.service");
12
+ let GracefulShutdownModule = class GracefulShutdownModule {
13
+ };
14
+ exports.GracefulShutdownModule = GracefulShutdownModule;
15
+ exports.GracefulShutdownModule = GracefulShutdownModule = __decorate([
16
+ (0, common_1.Global)(),
17
+ (0, common_1.Module)({
18
+ providers: [graceful_shutdown_service_1.GracefulShutdownService],
19
+ exports: [graceful_shutdown_service_1.GracefulShutdownService],
20
+ })
21
+ ], GracefulShutdownModule);
@@ -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;
@@ -0,0 +1,16 @@
1
+ import { OnApplicationShutdown, OnModuleDestroy, OnApplicationBootstrap } from '@nestjs/common';
2
+ interface GracefulExecInterceptor {
3
+ method: string;
4
+ traceId?: string;
5
+ correlationId: string;
6
+ }
7
+ export declare class GracefulShutdownService implements OnApplicationShutdown, OnModuleDestroy, OnApplicationBootstrap {
8
+ private activeInterceptors;
9
+ isApplicationExit: boolean;
10
+ onApplicationBootstrap(): void;
11
+ pushActiveInterceptors(execInterceptor: GracefulExecInterceptor): void;
12
+ popActiveInterceptors(execInterceptor: GracefulExecInterceptor): void;
13
+ onApplicationShutdown(signal?: string): Promise<void>;
14
+ onModuleDestroy(): Promise<void>;
15
+ }
16
+ export {};
@@ -35,19 +35,42 @@ const msa_logger_1 = __importStar(require("@yolo-croket-dev/msa-logger"));
35
35
  const msaLogger = new msa_logger_1.default(msa_logger_1.ServerTypeEnum.SERVICE);
36
36
  let GracefulShutdownService = class GracefulShutdownService {
37
37
  constructor() {
38
- this.activeInterceptors = 0;
38
+ this.activeInterceptors = [];
39
+ this.isApplicationExit = false;
39
40
  }
40
- incActiveInterceptors() {
41
- this.activeInterceptors += 1;
41
+ onApplicationBootstrap() {
42
+ this.activeInterceptors = [];
42
43
  }
43
- decActiveInterceptors() {
44
- this.activeInterceptors -= 1;
44
+ pushActiveInterceptors(execInterceptor) {
45
+ this.activeInterceptors.push(execInterceptor);
46
+ }
47
+ popActiveInterceptors(execInterceptor) {
48
+ // eslint-disable-next-line max-len
49
+ this.activeInterceptors = this.activeInterceptors.filter((item) => item.method === execInterceptor.method && item.traceId === execInterceptor.traceId && item.correlationId === execInterceptor.correlationId);
45
50
  }
46
51
  async onApplicationShutdown(signal) {
47
- msaLogger.debug(`GracefulShutdownService.onApplicationShutdown: ${signal}`, { traceId: 'ON_APPLICATION_SHUTDOWN' });
48
- while (this.activeInterceptors > 0) {
52
+ console.debug(`GracefulShutdownService.onApplicationShutdown signal=${signal}`, { traceId: 'ON_APPLICATION_SHUTDOWN' });
53
+ msaLogger.debug(`GracefulShutdownService.onApplicationShutdown signal=${signal}`, { traceId: 'ON_APPLICATION_SHUTDOWN' });
54
+ process.exit(0);
55
+ }
56
+ async onModuleDestroy() {
57
+ this.isApplicationExit = true;
58
+ msaLogger.debug('GracefulShutdownService.onModuleDestroy', { traceId: 'ON_MODULE_DESTROY' });
59
+ // eslint-disable-next-line max-len
60
+ msaLogger.debug('GracefulShutdownService.onModuleDestroy activeInterceptors', { traceId: 'ON_MODULE_DESTROY' }, { activeInterceptors: this.activeInterceptors });
61
+ // eslint-disable-next-line max-len
62
+ console.debug('GracefulShutdownService.onModuleDestroy activeInterceptors', { traceId: 'ON_MODULE_DESTROY' }, { activeInterceptors: this.activeInterceptors });
63
+ let prevExecInterceptorCount = 0;
64
+ while (this.activeInterceptors.length) {
65
+ if (prevExecInterceptorCount !== this.activeInterceptors.length) {
66
+ prevExecInterceptorCount = this.activeInterceptors.length;
67
+ // eslint-disable-next-line max-len
68
+ console.log(`GracefulShutdownService.onModuleDestroy: waiting for ${this.activeInterceptors} interceptors to finish`, { traceId: 'ON_MODULE_DESTROY' }, { activeInterceptors: this.activeInterceptors });
69
+ // eslint-disable-next-line max-len
70
+ msaLogger.debug(`GracefulShutdownService.onModuleDestroy: waiting for ${this.activeInterceptors} interceptors to finish`, { traceId: 'ON_MODULE_DESTROY' }, { activeInterceptors: this.activeInterceptors });
71
+ }
49
72
  await new Promise((resolve) => {
50
- setTimeout(resolve, 100);
73
+ setTimeout(resolve, 1000);
51
74
  });
52
75
  }
53
76
  }
@@ -1 +1,2 @@
1
1
  export * from './redis.module';
2
+ export * from './graceful-shutdown/graceful-shutdown.module';
package/modules/index.js CHANGED
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./redis.module"), exports);
18
+ __exportStar(require("./graceful-shutdown/graceful-shutdown.module"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yolo-croket-dev/core",
3
- "version": "1.4.53-slowquery.0",
3
+ "version": "1.4.53-slowquery.10",
4
4
  "author": "Yolo Co., Ltd.",
5
5
  "description": "Yolo commonization module",
6
6
  "main": "index.js",
@@ -1,7 +0,0 @@
1
- import { OnApplicationShutdown } from '@nestjs/common';
2
- export declare class GracefulShutdownService implements OnApplicationShutdown {
3
- private activeInterceptors;
4
- incActiveInterceptors(): void;
5
- decActiveInterceptors(): void;
6
- onApplicationShutdown(signal?: string): Promise<void>;
7
- }
@@ -1 +0,0 @@
1
- export * from './graceful-shutdown.service';
package/services/index.js DELETED
@@ -1,17 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./graceful-shutdown.service"), exports);