@abyss-project/monitor 1.0.56 → 1.0.58

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.
@@ -49,4 +49,5 @@ export declare function Middlewares(middlewares: Middleware[]): any;
49
49
  export declare function Body(schema: Joi.Schema, options?: ValidationOptions): any;
50
50
  export declare function Params(schema: Joi.Schema, options?: ValidationOptions): any;
51
51
  export declare function Query(schema: Joi.Schema, options?: ValidationOptions): any;
52
+ export declare function Killable(): any;
52
53
  export {};
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Query = exports.Params = exports.Body = exports.Middlewares = exports.Middleware = exports.Controller = exports.Patch = exports.Delete = exports.Put = exports.Post = exports.Get = void 0;
6
+ exports.Killable = exports.Query = exports.Params = exports.Body = exports.Middlewares = exports.Middleware = exports.Controller = exports.Patch = exports.Delete = exports.Put = exports.Post = exports.Get = void 0;
7
7
  const types_1 = require("../../types");
8
8
  const _1 = require(".");
9
9
  const joi_to_swagger_1 = __importDefault(require("joi-to-swagger"));
@@ -161,3 +161,9 @@ function Query(schema, options) {
161
161
  };
162
162
  }
163
163
  exports.Query = Query;
164
+ function Killable() {
165
+ return function (target, propertyKey, descriptor) {
166
+ Reflect.defineMetadata(_1.KILLABLE_WATERMARK, true, target, propertyKey);
167
+ };
168
+ }
169
+ exports.Killable = Killable;
@@ -7,3 +7,4 @@ export declare const ROUTE_WATERMARK = "__route__";
7
7
  export declare const DOCS_WATERMARK = "__docs__";
8
8
  export declare const MIDDLEWARE_WATERMARK = "__middleware__";
9
9
  export declare const MIDDLEWARE_HOOK_WATERMARK = "__middleware_hook__";
10
+ export declare const KILLABLE_WATERMARK = "__killable__";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MIDDLEWARE_HOOK_WATERMARK = exports.MIDDLEWARE_WATERMARK = exports.DOCS_WATERMARK = exports.ROUTE_WATERMARK = exports.OPTIONS_WATERMARK = exports.METHOD_WATERMARK = exports.PATH_WATERMARK = exports.MASKED_WATERMARK = exports.CONTROLLER_WATERMARK = void 0;
3
+ exports.KILLABLE_WATERMARK = exports.MIDDLEWARE_HOOK_WATERMARK = exports.MIDDLEWARE_WATERMARK = exports.DOCS_WATERMARK = exports.ROUTE_WATERMARK = exports.OPTIONS_WATERMARK = exports.METHOD_WATERMARK = exports.PATH_WATERMARK = exports.MASKED_WATERMARK = exports.CONTROLLER_WATERMARK = void 0;
4
4
  exports.CONTROLLER_WATERMARK = '__controller__';
5
5
  exports.MASKED_WATERMARK = '__masked__';
6
6
  exports.PATH_WATERMARK = '__path__';
@@ -10,3 +10,4 @@ exports.ROUTE_WATERMARK = '__route__';
10
10
  exports.DOCS_WATERMARK = '__docs__';
11
11
  exports.MIDDLEWARE_WATERMARK = '__middleware__';
12
12
  exports.MIDDLEWARE_HOOK_WATERMARK = '__middleware_hook__';
13
+ exports.KILLABLE_WATERMARK = '__killable__';
@@ -1,3 +1,8 @@
1
1
  import { Request, Response, NextFunction } from 'express-serve-static-core';
2
2
  import { Logger } from '../models/logger.model';
3
- export declare const createRequestTrackerMiddleware: (logger?: Logger) => (req: Request, res: Response, next: NextFunction) => void;
3
+ export type IsKillableFn = (req: Request) => boolean;
4
+ export interface RequestTrackerOptions {
5
+ logger?: Logger;
6
+ isKillable?: IsKillableFn;
7
+ }
8
+ export declare const createRequestTrackerMiddleware: (options?: RequestTrackerOptions) => (req: Request, res: Response, next: NextFunction) => void;
@@ -3,8 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createRequestTrackerMiddleware = void 0;
4
4
  const request_tracker_utils_1 = require("../utils/request-tracker.utils");
5
5
  const graceful_shutdown_types_1 = require("../types/graceful-shutdown.types");
6
- const createRequestTrackerMiddleware = (logger) => {
6
+ const killable_route_utils_1 = require("../utils/killable-route.utils");
7
+ const createRequestTrackerMiddleware = (options) => {
8
+ const { logger, isKillable } = options || {};
7
9
  return (req, res, next) => {
10
+ const requestIsKillable = isKillable ? isKillable(req) : (0, killable_route_utils_1.isRouteKillable)(req);
8
11
  if ((0, request_tracker_utils_1.getIsShuttingDown)()) {
9
12
  res.status(503).json({
10
13
  errorCode: graceful_shutdown_types_1.GracefulShutdownErrorCode.SERVICE_UNAVAILABLE,
@@ -12,13 +15,13 @@ const createRequestTrackerMiddleware = (logger) => {
12
15
  });
13
16
  return;
14
17
  }
15
- (0, request_tracker_utils_1.incrementActiveRequests)();
18
+ (0, request_tracker_utils_1.incrementActiveRequests)(requestIsKillable);
16
19
  let cleaned = false;
17
20
  const cleanup = () => {
18
21
  if (cleaned)
19
22
  return;
20
23
  cleaned = true;
21
- (0, request_tracker_utils_1.decrementActiveRequests)();
24
+ (0, request_tracker_utils_1.decrementActiveRequests)(requestIsKillable);
22
25
  };
23
26
  res.on('finish', cleanup);
24
27
  res.on('close', cleanup);
@@ -3,20 +3,39 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setupGracefulShutdown = void 0;
4
4
  const request_tracker_utils_1 = require("../utils/request-tracker.utils");
5
5
  const graceful_shutdown_types_1 = require("../types/graceful-shutdown.types");
6
+ const types_1 = require("../types");
6
7
  const DEFAULT_SHUTDOWN_TIMEOUT = 30000;
7
8
  const DEFAULT_REQUESTS_TIMEOUT = 25000;
8
9
  const DEFAULT_CHECK_INTERVAL = 100;
10
+ const createGracefulShutdownLogger = (baseLogger) => {
11
+ const defaultPayload = {
12
+ context: 'GracefulShutdown',
13
+ scenario: types_1.LogScenario.SYSTEM_STARTUP,
14
+ };
15
+ const wrappedLogger = Object.create(baseLogger);
16
+ wrappedLogger.log = (message, payload, options) => baseLogger.log(message, { ...defaultPayload, ...payload }, options);
17
+ wrappedLogger.info = (message, payload, options) => baseLogger.info(message, { ...defaultPayload, ...payload }, options);
18
+ wrappedLogger.debug = (message, payload, options) => baseLogger.debug(message, { ...defaultPayload, ...payload }, options);
19
+ wrappedLogger.warn = (message, payload, options) => baseLogger.warn(message, { ...defaultPayload, ...payload }, options);
20
+ wrappedLogger.error = (message, payload, options) => baseLogger.error(message, { ...defaultPayload, ...payload }, options);
21
+ return wrappedLogger;
22
+ };
9
23
  const setupGracefulShutdown = (config) => {
10
- const { logger, httpServer, databases = [], messageQueues = [], caches = [], otherResources = [], shutdownTimeout = DEFAULT_SHUTDOWN_TIMEOUT, requestsTimeout = DEFAULT_REQUESTS_TIMEOUT, checkInterval = DEFAULT_CHECK_INTERVAL, } = config;
24
+ const { logger: baseLogger, httpServer, databases = [], messageQueues = [], caches = [], otherResources = [], shutdownTimeout = DEFAULT_SHUTDOWN_TIMEOUT, requestsTimeout = DEFAULT_REQUESTS_TIMEOUT, checkInterval = DEFAULT_CHECK_INTERVAL, } = config;
25
+ const logger = createGracefulShutdownLogger(baseLogger);
11
26
  const gracefulShutdown = async (signal) => {
12
27
  if ((0, request_tracker_utils_1.getIsShuttingDown)()) {
13
28
  logger.warn(`Already shutting down, ignoring ${signal}`);
14
29
  return;
15
30
  }
16
31
  (0, request_tracker_utils_1.setIsShuttingDown)(true);
17
- logger.info(`Received ${signal}, starting graceful shutdown...`, {
32
+ const totalRequests = (0, request_tracker_utils_1.getTotalRequestsCount)();
33
+ const killableRequests = (0, request_tracker_utils_1.getKillableRequestsCount)();
34
+ logger.log(`Received ${signal}, starting graceful shutdown...`, {
18
35
  data: {
19
36
  activeRequests: (0, request_tracker_utils_1.getActiveRequestsCount)(),
37
+ killableRequests,
38
+ totalRequests,
20
39
  },
21
40
  });
22
41
  const forceShutdownTimer = setTimeout(() => {
@@ -31,7 +50,7 @@ const setupGracefulShutdown = (config) => {
31
50
  try {
32
51
  const activeRequests = (0, request_tracker_utils_1.getActiveRequestsCount)();
33
52
  if (activeRequests > 0) {
34
- logger.info(`Waiting for ${activeRequests} active requests to complete...`, {
53
+ logger.log(`Waiting for ${activeRequests} active requests to complete...`, {
35
54
  data: {
36
55
  activeRequests,
37
56
  timeoutMs: requestsTimeout,
@@ -60,7 +79,7 @@ const setupGracefulShutdown = (config) => {
60
79
  reject(err);
61
80
  }
62
81
  else {
63
- logger.info('HTTP server closed, no longer accepting new connections');
82
+ logger.log('HTTP server closed, no longer accepting new connections');
64
83
  resolve();
65
84
  }
66
85
  });
@@ -70,7 +89,7 @@ const setupGracefulShutdown = (config) => {
70
89
  await Promise.allSettled(messageQueues.map(async (mq) => {
71
90
  try {
72
91
  await mq.close();
73
- logger.info(`Message queue connection closed${mq.name ? `: ${mq.name}` : ''}`);
92
+ logger.log(`Message queue connection closed${mq.name ? `: ${mq.name}` : ''}`);
74
93
  }
75
94
  catch (error) {
76
95
  logger.error(`Error closing message queue connection${mq.name ? `: ${mq.name}` : ''}`, {
@@ -86,7 +105,7 @@ const setupGracefulShutdown = (config) => {
86
105
  await Promise.allSettled(caches.map(async (cache) => {
87
106
  try {
88
107
  await cache.close();
89
- logger.info(`Cache connection closed${cache.name ? `: ${cache.name}` : ''}`);
108
+ logger.log(`Cache connection closed${cache.name ? `: ${cache.name}` : ''}`);
90
109
  }
91
110
  catch (error) {
92
111
  logger.error(`Error closing cache connection${cache.name ? `: ${cache.name}` : ''}`, {
@@ -102,7 +121,7 @@ const setupGracefulShutdown = (config) => {
102
121
  await Promise.allSettled(databases.map(async (db) => {
103
122
  try {
104
123
  await db.close();
105
- logger.info(`Database connection closed${db.name ? `: ${db.name}` : ''}`);
124
+ logger.log(`Database connection closed${db.name ? `: ${db.name}` : ''}`);
106
125
  }
107
126
  catch (error) {
108
127
  logger.error(`Error closing database connection${db.name ? `: ${db.name}` : ''}`, {
@@ -118,7 +137,7 @@ const setupGracefulShutdown = (config) => {
118
137
  await Promise.allSettled(otherResources.map(async (resource) => {
119
138
  try {
120
139
  await resource.close();
121
- logger.info(`Resource closed${resource.name ? `: ${resource.name}` : ''}`);
140
+ logger.log(`Resource closed${resource.name ? `: ${resource.name}` : ''}`);
122
141
  }
123
142
  catch (error) {
124
143
  logger.error(`Error closing resource${resource.name ? `: ${resource.name}` : ''}`, {
@@ -130,7 +149,7 @@ const setupGracefulShutdown = (config) => {
130
149
  }
131
150
  }));
132
151
  }
133
- logger.info('Graceful shutdown completed successfully');
152
+ logger.log('Graceful shutdown completed successfully');
134
153
  clearTimeout(forceShutdownTimer);
135
154
  process.exit(0);
136
155
  }
@@ -164,6 +183,6 @@ const setupGracefulShutdown = (config) => {
164
183
  });
165
184
  gracefulShutdown('unhandledRejection');
166
185
  });
167
- logger.info('Graceful shutdown handlers registered');
186
+ logger.log('Graceful shutdown handlers registered');
168
187
  };
169
188
  exports.setupGracefulShutdown = setupGracefulShutdown;
@@ -0,0 +1,3 @@
1
+ import 'reflect-metadata';
2
+ import { Request } from 'express-serve-static-core';
3
+ export declare const isRouteKillable: (req: Request) => boolean;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isRouteKillable = void 0;
4
+ require("reflect-metadata");
5
+ const metadata_1 = require("../frameworks/express/metadata");
6
+ const isRouteKillable = (req) => {
7
+ const route = req.route;
8
+ if (!route || !route.stack || route.stack.length === 0) {
9
+ return false;
10
+ }
11
+ for (const layer of route.stack) {
12
+ const handler = layer.handle;
13
+ if (!handler)
14
+ continue;
15
+ const prototype = Object.getPrototypeOf(handler);
16
+ if (prototype && prototype.constructor) {
17
+ const propertyKey = handler.name;
18
+ const isKillable = Reflect.getMetadata(metadata_1.KILLABLE_WATERMARK, prototype.constructor.prototype, propertyKey);
19
+ if (isKillable) {
20
+ return true;
21
+ }
22
+ }
23
+ }
24
+ return false;
25
+ };
26
+ exports.isRouteKillable = isRouteKillable;
@@ -1,7 +1,9 @@
1
1
  import { Logger } from '../models/logger.model';
2
2
  export declare const getActiveRequestsCount: () => number;
3
+ export declare const getKillableRequestsCount: () => number;
4
+ export declare const getTotalRequestsCount: () => number;
3
5
  export declare const getIsShuttingDown: () => boolean;
4
6
  export declare const setIsShuttingDown: (value: boolean) => void;
5
- export declare const incrementActiveRequests: () => void;
6
- export declare const decrementActiveRequests: () => void;
7
+ export declare const incrementActiveRequests: (isKillable?: boolean) => void;
8
+ export declare const decrementActiveRequests: (isKillable?: boolean) => void;
7
9
  export declare const waitForActiveRequests: (timeout?: number, checkInterval?: number, logger?: Logger) => Promise<void>;
@@ -1,23 +1,38 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.waitForActiveRequests = exports.decrementActiveRequests = exports.incrementActiveRequests = exports.setIsShuttingDown = exports.getIsShuttingDown = exports.getActiveRequestsCount = void 0;
3
+ exports.waitForActiveRequests = exports.decrementActiveRequests = exports.incrementActiveRequests = exports.setIsShuttingDown = exports.getIsShuttingDown = exports.getTotalRequestsCount = exports.getKillableRequestsCount = exports.getActiveRequestsCount = void 0;
4
4
  const graceful_shutdown_types_1 = require("../types/graceful-shutdown.types");
5
5
  let activeRequests = 0;
6
+ let killableRequests = 0;
6
7
  let isShuttingDown = false;
7
8
  const getActiveRequestsCount = () => activeRequests;
8
9
  exports.getActiveRequestsCount = getActiveRequestsCount;
10
+ const getKillableRequestsCount = () => killableRequests;
11
+ exports.getKillableRequestsCount = getKillableRequestsCount;
12
+ const getTotalRequestsCount = () => activeRequests + killableRequests;
13
+ exports.getTotalRequestsCount = getTotalRequestsCount;
9
14
  const getIsShuttingDown = () => isShuttingDown;
10
15
  exports.getIsShuttingDown = getIsShuttingDown;
11
16
  const setIsShuttingDown = (value) => {
12
17
  isShuttingDown = value;
13
18
  };
14
19
  exports.setIsShuttingDown = setIsShuttingDown;
15
- const incrementActiveRequests = () => {
16
- activeRequests++;
20
+ const incrementActiveRequests = (isKillable = false) => {
21
+ if (isKillable) {
22
+ killableRequests++;
23
+ }
24
+ else {
25
+ activeRequests++;
26
+ }
17
27
  };
18
28
  exports.incrementActiveRequests = incrementActiveRequests;
19
- const decrementActiveRequests = () => {
20
- activeRequests--;
29
+ const decrementActiveRequests = (isKillable = false) => {
30
+ if (isKillable) {
31
+ killableRequests--;
32
+ }
33
+ else {
34
+ activeRequests--;
35
+ }
21
36
  };
22
37
  exports.decrementActiveRequests = decrementActiveRequests;
23
38
  const waitForActiveRequests = async (timeout = 30000, checkInterval = 100, logger) => {
@@ -25,7 +40,7 @@ const waitForActiveRequests = async (timeout = 30000, checkInterval = 100, logge
25
40
  return new Promise((resolve, reject) => {
26
41
  const check = () => {
27
42
  if (activeRequests === 0) {
28
- logger === null || logger === void 0 ? void 0 : logger.info('All active requests completed');
43
+ logger === null || logger === void 0 ? void 0 : logger.log('All active requests completed');
29
44
  resolve();
30
45
  return;
31
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abyss-project/monitor",
3
- "version": "1.0.56",
3
+ "version": "1.0.58",
4
4
  "description": "Core package to interact with Abyss-Monitor",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",