imean-service-engine 1.4.2 → 1.6.0

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/dist/mod.cjs CHANGED
@@ -292,8 +292,6 @@ async function formatCode(code) {
292
292
  return code;
293
293
  }
294
294
  }
295
-
296
- // core/generator.ts
297
295
  function getZodTypeString(schema, defaultOptional = false) {
298
296
  function processType(type) {
299
297
  const def = type._def;
@@ -303,6 +301,9 @@ function getZodTypeString(schema, defaultOptional = false) {
303
301
  if (def.typeName === "ZodOptional") {
304
302
  return processType(def.innerType);
305
303
  }
304
+ if (def.typeName === "ZodEffects" && def.schema?._def.typeName !== "ZodAny") {
305
+ return processType(def.schema);
306
+ }
306
307
  switch (def.typeName) {
307
308
  case "ZodString": {
308
309
  return "string";
@@ -310,6 +311,9 @@ function getZodTypeString(schema, defaultOptional = false) {
310
311
  case "ZodNumber": {
311
312
  return "number";
312
313
  }
314
+ case "ZodBigInt": {
315
+ return "bigint";
316
+ }
313
317
  case "ZodBoolean": {
314
318
  return "boolean";
315
319
  }
@@ -775,10 +779,11 @@ var Microservice = class {
775
779
  lease;
776
780
  scheduler;
777
781
  abortController;
778
- isShuttingDown = false;
779
782
  statisticsTimer;
780
783
  wsHandler;
781
784
  actionHandlers = /* @__PURE__ */ new Map();
785
+ activeRequests = /* @__PURE__ */ new Map();
786
+ status = "running";
782
787
  modules = /* @__PURE__ */ new Map();
783
788
  fetch;
784
789
  options;
@@ -801,6 +806,10 @@ var Microservice = class {
801
806
  websocket: { enabled: false },
802
807
  cacheAdapter: new MemoryCacheAdapter(),
803
808
  plugins: [],
809
+ gracefulShutdown: {
810
+ timeout: 3e4,
811
+ cleanupHooks: []
812
+ },
804
813
  ...options
805
814
  };
806
815
  this.cache = this.options.cacheAdapter;
@@ -879,7 +888,7 @@ var Microservice = class {
879
888
  this.app.get(prefix, (ctx) => {
880
889
  const name = this.options.name ?? "Microservice";
881
890
  const version = this.options.version ?? "1.0.0";
882
- return ctx.text(`${name} is running. version: ${version}`);
891
+ return ctx.text(`${name} is ${this.status}. version: ${version}`);
883
892
  });
884
893
  this.app.get(`${prefix}/health`, (ctx) => {
885
894
  return ctx.json({
@@ -895,7 +904,9 @@ var Microservice = class {
895
904
  version: this.options.version,
896
905
  env: this.options.env,
897
906
  modules: this.getModules(),
898
- stats: Object.fromEntries(this.statsMap)
907
+ stats: Object.fromEntries(this.statsMap),
908
+ activeRequests: this.getActiveRequestCount(),
909
+ status: this.status
899
910
  });
900
911
  });
901
912
  this.app.get(`${prefix}/client.ts`, async (ctx) => {
@@ -1092,7 +1103,12 @@ var Microservice = class {
1092
1103
  process.on("SIGINT", () => {
1093
1104
  logger_default.info(`
1094
1105
  Received SIGINT signal`);
1095
- this.gracefulShutdown();
1106
+ this.shutdown();
1107
+ });
1108
+ process.on("SIGTERM", () => {
1109
+ logger_default.info(`
1110
+ Received SIGTERM signal`);
1111
+ this.shutdown();
1096
1112
  });
1097
1113
  process.on("unhandledrejection", (event) => {
1098
1114
  logger_default.error("Unhandled rejection:", event.reason);
@@ -1104,14 +1120,16 @@ Received SIGINT signal`);
1104
1120
  /**
1105
1121
  * 优雅停机
1106
1122
  */
1107
- async gracefulShutdown() {
1108
- if (this.isShuttingDown) return;
1109
- this.isShuttingDown = true;
1110
- logger_default.info("\nGraceful shutdown initiated...");
1123
+ async shutdown() {
1124
+ if (this.status === "shutting_down") return;
1125
+ this.status = "shutting_down";
1126
+ logger_default.info("\nshutdown initiated...");
1111
1127
  if (this.statisticsTimer) clearInterval(this.statisticsTimer);
1112
1128
  try {
1129
+ await this.waitForActiveRequests();
1130
+ await this.executeCleanupHooks();
1113
1131
  await this.stop();
1114
- logger_default.info("Graceful shutdown completed");
1132
+ logger_default.info("shutdown completed");
1115
1133
  } catch (error) {
1116
1134
  logger_default.error("Error during shutdown:", error);
1117
1135
  process.exit(1);
@@ -1119,6 +1137,57 @@ Received SIGINT signal`);
1119
1137
  process.exit(0);
1120
1138
  }
1121
1139
  }
1140
+ /**
1141
+ * 等待所有活跃请求完成
1142
+ */
1143
+ async waitForActiveRequests() {
1144
+ const timeout = this.options.gracefulShutdown?.timeout || 3e4;
1145
+ const startTime = Date.now();
1146
+ logger_default.info(`Waiting for ${this.activeRequests.size} active requests to complete...`);
1147
+ return new Promise((resolve) => {
1148
+ const checkInterval = setInterval(() => {
1149
+ const elapsed = Date.now() - startTime;
1150
+ if (this.activeRequests.size === 0) {
1151
+ clearInterval(checkInterval);
1152
+ logger_default.info("All active requests completed");
1153
+ resolve();
1154
+ } else if (elapsed >= timeout) {
1155
+ clearInterval(checkInterval);
1156
+ logger_default.warn(`Timeout waiting for requests to complete. ${this.activeRequests.size} requests still active`);
1157
+ resolve();
1158
+ } else {
1159
+ logger_default.info(`Still waiting for ${this.activeRequests.size} requests... (${elapsed}ms elapsed)`);
1160
+ }
1161
+ }, 1e3);
1162
+ });
1163
+ }
1164
+ /**
1165
+ * 执行清理hook
1166
+ */
1167
+ async executeCleanupHooks() {
1168
+ const hooks = this.options.gracefulShutdown?.cleanupHooks || [];
1169
+ if (hooks.length === 0) {
1170
+ logger_default.info("No cleanup hooks configured");
1171
+ return;
1172
+ }
1173
+ logger_default.info(`Executing ${hooks.length} cleanup hooks...`);
1174
+ for (const hook of hooks) {
1175
+ try {
1176
+ const timeout = hook.timeout || 5e3;
1177
+ logger_default.info(`Executing cleanup hook: ${hook.name}`);
1178
+ await Promise.race([
1179
+ Promise.resolve(hook.cleanup()),
1180
+ new Promise(
1181
+ (_, reject) => setTimeout(() => reject(new Error(`Cleanup hook ${hook.name} timeout`)), timeout)
1182
+ )
1183
+ ]);
1184
+ logger_default.info(`Cleanup hook ${hook.name} completed successfully`);
1185
+ } catch (error) {
1186
+ logger_default.error(`Cleanup hook ${hook.name} failed:`, error);
1187
+ }
1188
+ }
1189
+ logger_default.info("All cleanup hooks completed");
1190
+ }
1122
1191
  initStatsEventManager() {
1123
1192
  this.statisticsTimer = setInterval(async () => {
1124
1193
  await this.updateStats();
@@ -1160,14 +1229,54 @@ Received SIGINT signal`);
1160
1229
  }
1161
1230
  return handler;
1162
1231
  }
1232
+ /**
1233
+ * 添加活跃请求跟踪
1234
+ */
1235
+ addActiveRequest(requestId, requestInfo) {
1236
+ this.activeRequests.set(requestId, requestInfo);
1237
+ }
1238
+ /**
1239
+ * 移除活跃请求跟踪
1240
+ */
1241
+ removeActiveRequest(requestId) {
1242
+ this.activeRequests.delete(requestId);
1243
+ }
1244
+ /**
1245
+ * 获取当前活跃请求数量
1246
+ */
1247
+ getActiveRequestCount() {
1248
+ return this.activeRequests.size;
1249
+ }
1250
+ /**
1251
+ * 获取当前活跃请求信息
1252
+ */
1253
+ getActiveRequests() {
1254
+ return Array.from(this.activeRequests.values());
1255
+ }
1163
1256
  handleRequest = async (ctx) => {
1164
1257
  const { moduleName, actionName } = ctx.req.param();
1165
1258
  const handler = this.getActionHandler(moduleName, actionName);
1259
+ const requestId = crypto.randomUUID();
1260
+ const startTime = Date.now();
1261
+ if (this.status === "shutting_down") {
1262
+ return ctx.json({
1263
+ success: false,
1264
+ error: "Service is shutting down"
1265
+ }, 503);
1266
+ }
1166
1267
  try {
1167
1268
  const paramsText = await ctx.req.text();
1269
+ this.addActiveRequest(requestId, {
1270
+ id: requestId,
1271
+ moduleName,
1272
+ actionName,
1273
+ startTime,
1274
+ params: paramsText
1275
+ });
1168
1276
  const result = await handler.handle(paramsText);
1169
1277
  if (handler.metadata.stream) {
1170
1278
  const encoder = new TextEncoder();
1279
+ const microservice = this;
1171
1280
  const stream = new ReadableStream({
1172
1281
  async start(controller) {
1173
1282
  try {
@@ -1191,6 +1300,8 @@ Received SIGINT signal`);
1191
1300
  encoder.encode(ejson4__default.default.stringify(response) + "\n")
1192
1301
  );
1193
1302
  controller.close();
1303
+ } finally {
1304
+ microservice.removeActiveRequest(requestId);
1194
1305
  }
1195
1306
  }
1196
1307
  });
@@ -1202,8 +1313,10 @@ Received SIGINT signal`);
1202
1313
  }
1203
1314
  });
1204
1315
  }
1316
+ this.removeActiveRequest(requestId);
1205
1317
  return ctx.text(ejson4__default.default.stringify({ success: true, data: result }));
1206
1318
  } catch (error) {
1319
+ this.removeActiveRequest(requestId);
1207
1320
  return ctx.json({ success: false, error: error.message });
1208
1321
  }
1209
1322
  };
package/dist/mod.d.cts CHANGED
@@ -155,6 +155,32 @@ interface MicroserviceOptions {
155
155
  };
156
156
  cacheAdapter?: CacheAdapter;
157
157
  plugins?: Plugin[];
158
+ gracefulShutdown?: {
159
+ /** 优雅停机超时时间(毫秒),默认 30 秒 */
160
+ timeout?: number;
161
+ /** 清理hook列表 */
162
+ cleanupHooks?: CleanupHook[];
163
+ };
164
+ }
165
+ interface CleanupHook {
166
+ /** hook名称 */
167
+ name: string;
168
+ /** 清理函数 */
169
+ cleanup: () => Promise<void> | void;
170
+ /** 超时时间(毫秒),默认 5 秒 */
171
+ timeout?: number;
172
+ }
173
+ interface RequestInfo {
174
+ /** 请求ID */
175
+ id: string;
176
+ /** 模块名称 */
177
+ moduleName: string;
178
+ /** 动作名称 */
179
+ actionName: string;
180
+ /** 开始时间 */
181
+ startTime: number;
182
+ /** 请求参数 */
183
+ params?: any;
158
184
  }
159
185
  interface ModuleInfo extends ModuleOptions {
160
186
  actions: Record<string, ActionMetadata>;
@@ -197,10 +223,11 @@ declare class Microservice {
197
223
  private lease?;
198
224
  private scheduler?;
199
225
  private abortController?;
200
- private isShuttingDown;
201
226
  private statisticsTimer?;
202
227
  private wsHandler?;
203
228
  private actionHandlers;
229
+ private activeRequests;
230
+ private status;
204
231
  modules: Map<string, ModuleInfo>;
205
232
  readonly fetch: typeof fetch;
206
233
  options: Required<MicroserviceOptions>;
@@ -236,7 +263,7 @@ declare class Microservice {
236
263
  /**
237
264
  * 停止服务
238
265
  */
239
- stop(): Promise<void>;
266
+ private stop;
240
267
  /**
241
268
  * 初始化停机处理
242
269
  */
@@ -244,10 +271,34 @@ declare class Microservice {
244
271
  /**
245
272
  * 优雅停机
246
273
  */
247
- private gracefulShutdown;
274
+ shutdown(): Promise<void>;
275
+ /**
276
+ * 等待所有活跃请求完成
277
+ */
278
+ private waitForActiveRequests;
279
+ /**
280
+ * 执行清理hook
281
+ */
282
+ private executeCleanupHooks;
248
283
  private initStatsEventManager;
249
284
  private updateStats;
250
285
  getActionHandler(moduleName: string, actionName: string): ActionHandler;
286
+ /**
287
+ * 添加活跃请求跟踪
288
+ */
289
+ private addActiveRequest;
290
+ /**
291
+ * 移除活跃请求跟踪
292
+ */
293
+ private removeActiveRequest;
294
+ /**
295
+ * 获取当前活跃请求数量
296
+ */
297
+ getActiveRequestCount(): number;
298
+ /**
299
+ * 获取当前活跃请求信息
300
+ */
301
+ getActiveRequests(): RequestInfo[];
251
302
  private handleRequest;
252
303
  private initPlugins;
253
304
  init(): Promise<void>;
@@ -286,4 +337,4 @@ declare function Schedule(options: ScheduleOptions): Function;
286
337
 
287
338
  declare const logger: winston.Logger;
288
339
 
289
- export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, CacheAdapter, type CacheFn, type EtcdConfig, type EventServiceInfo, type McpOptions, MemoryCacheAdapter, Microservice, type MicroserviceOptions, ModelContextProtocolPlugin, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Plugin, type PreStartChecker, RedisCacheAdapter, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, type ServiceStats, type StatisticsEvent, type StreamResponse, logger, startCheck };
340
+ export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, CacheAdapter, type CacheFn, type CleanupHook, type EtcdConfig, type EventServiceInfo, type McpOptions, MemoryCacheAdapter, Microservice, type MicroserviceOptions, ModelContextProtocolPlugin, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Plugin, type PreStartChecker, RedisCacheAdapter, type RequestInfo, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, type ServiceStats, type StatisticsEvent, type StreamResponse, logger, startCheck };
package/dist/mod.d.ts CHANGED
@@ -155,6 +155,32 @@ interface MicroserviceOptions {
155
155
  };
156
156
  cacheAdapter?: CacheAdapter;
157
157
  plugins?: Plugin[];
158
+ gracefulShutdown?: {
159
+ /** 优雅停机超时时间(毫秒),默认 30 秒 */
160
+ timeout?: number;
161
+ /** 清理hook列表 */
162
+ cleanupHooks?: CleanupHook[];
163
+ };
164
+ }
165
+ interface CleanupHook {
166
+ /** hook名称 */
167
+ name: string;
168
+ /** 清理函数 */
169
+ cleanup: () => Promise<void> | void;
170
+ /** 超时时间(毫秒),默认 5 秒 */
171
+ timeout?: number;
172
+ }
173
+ interface RequestInfo {
174
+ /** 请求ID */
175
+ id: string;
176
+ /** 模块名称 */
177
+ moduleName: string;
178
+ /** 动作名称 */
179
+ actionName: string;
180
+ /** 开始时间 */
181
+ startTime: number;
182
+ /** 请求参数 */
183
+ params?: any;
158
184
  }
159
185
  interface ModuleInfo extends ModuleOptions {
160
186
  actions: Record<string, ActionMetadata>;
@@ -197,10 +223,11 @@ declare class Microservice {
197
223
  private lease?;
198
224
  private scheduler?;
199
225
  private abortController?;
200
- private isShuttingDown;
201
226
  private statisticsTimer?;
202
227
  private wsHandler?;
203
228
  private actionHandlers;
229
+ private activeRequests;
230
+ private status;
204
231
  modules: Map<string, ModuleInfo>;
205
232
  readonly fetch: typeof fetch;
206
233
  options: Required<MicroserviceOptions>;
@@ -236,7 +263,7 @@ declare class Microservice {
236
263
  /**
237
264
  * 停止服务
238
265
  */
239
- stop(): Promise<void>;
266
+ private stop;
240
267
  /**
241
268
  * 初始化停机处理
242
269
  */
@@ -244,10 +271,34 @@ declare class Microservice {
244
271
  /**
245
272
  * 优雅停机
246
273
  */
247
- private gracefulShutdown;
274
+ shutdown(): Promise<void>;
275
+ /**
276
+ * 等待所有活跃请求完成
277
+ */
278
+ private waitForActiveRequests;
279
+ /**
280
+ * 执行清理hook
281
+ */
282
+ private executeCleanupHooks;
248
283
  private initStatsEventManager;
249
284
  private updateStats;
250
285
  getActionHandler(moduleName: string, actionName: string): ActionHandler;
286
+ /**
287
+ * 添加活跃请求跟踪
288
+ */
289
+ private addActiveRequest;
290
+ /**
291
+ * 移除活跃请求跟踪
292
+ */
293
+ private removeActiveRequest;
294
+ /**
295
+ * 获取当前活跃请求数量
296
+ */
297
+ getActiveRequestCount(): number;
298
+ /**
299
+ * 获取当前活跃请求信息
300
+ */
301
+ getActiveRequests(): RequestInfo[];
251
302
  private handleRequest;
252
303
  private initPlugins;
253
304
  init(): Promise<void>;
@@ -286,4 +337,4 @@ declare function Schedule(options: ScheduleOptions): Function;
286
337
 
287
338
  declare const logger: winston.Logger;
288
339
 
289
- export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, CacheAdapter, type CacheFn, type EtcdConfig, type EventServiceInfo, type McpOptions, MemoryCacheAdapter, Microservice, type MicroserviceOptions, ModelContextProtocolPlugin, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Plugin, type PreStartChecker, RedisCacheAdapter, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, type ServiceStats, type StatisticsEvent, type StreamResponse, logger, startCheck };
340
+ export { Action, type ActionErrorEvent, type ActionMetadata, type ActionOptions, CacheAdapter, type CacheFn, type CleanupHook, type EtcdConfig, type EventServiceInfo, type McpOptions, MemoryCacheAdapter, Microservice, type MicroserviceOptions, ModelContextProtocolPlugin, Module, type ModuleInfo, type ModuleMetadata, type ModuleOptions, Plugin, type PreStartChecker, RedisCacheAdapter, type RequestInfo, Schedule, type ScheduleMetadata, ScheduleMode, type ScheduleOptions, ServiceContext, type ServiceInfo, type ServiceStats, type StatisticsEvent, type StreamResponse, logger, startCheck };
package/dist/mod.js CHANGED
@@ -283,8 +283,6 @@ async function formatCode(code) {
283
283
  return code;
284
284
  }
285
285
  }
286
-
287
- // core/generator.ts
288
286
  function getZodTypeString(schema, defaultOptional = false) {
289
287
  function processType(type) {
290
288
  const def = type._def;
@@ -294,6 +292,9 @@ function getZodTypeString(schema, defaultOptional = false) {
294
292
  if (def.typeName === "ZodOptional") {
295
293
  return processType(def.innerType);
296
294
  }
295
+ if (def.typeName === "ZodEffects" && def.schema?._def.typeName !== "ZodAny") {
296
+ return processType(def.schema);
297
+ }
297
298
  switch (def.typeName) {
298
299
  case "ZodString": {
299
300
  return "string";
@@ -301,6 +302,9 @@ function getZodTypeString(schema, defaultOptional = false) {
301
302
  case "ZodNumber": {
302
303
  return "number";
303
304
  }
305
+ case "ZodBigInt": {
306
+ return "bigint";
307
+ }
304
308
  case "ZodBoolean": {
305
309
  return "boolean";
306
310
  }
@@ -766,10 +770,11 @@ var Microservice = class {
766
770
  lease;
767
771
  scheduler;
768
772
  abortController;
769
- isShuttingDown = false;
770
773
  statisticsTimer;
771
774
  wsHandler;
772
775
  actionHandlers = /* @__PURE__ */ new Map();
776
+ activeRequests = /* @__PURE__ */ new Map();
777
+ status = "running";
773
778
  modules = /* @__PURE__ */ new Map();
774
779
  fetch;
775
780
  options;
@@ -792,6 +797,10 @@ var Microservice = class {
792
797
  websocket: { enabled: false },
793
798
  cacheAdapter: new MemoryCacheAdapter(),
794
799
  plugins: [],
800
+ gracefulShutdown: {
801
+ timeout: 3e4,
802
+ cleanupHooks: []
803
+ },
795
804
  ...options
796
805
  };
797
806
  this.cache = this.options.cacheAdapter;
@@ -870,7 +879,7 @@ var Microservice = class {
870
879
  this.app.get(prefix, (ctx) => {
871
880
  const name = this.options.name ?? "Microservice";
872
881
  const version = this.options.version ?? "1.0.0";
873
- return ctx.text(`${name} is running. version: ${version}`);
882
+ return ctx.text(`${name} is ${this.status}. version: ${version}`);
874
883
  });
875
884
  this.app.get(`${prefix}/health`, (ctx) => {
876
885
  return ctx.json({
@@ -886,7 +895,9 @@ var Microservice = class {
886
895
  version: this.options.version,
887
896
  env: this.options.env,
888
897
  modules: this.getModules(),
889
- stats: Object.fromEntries(this.statsMap)
898
+ stats: Object.fromEntries(this.statsMap),
899
+ activeRequests: this.getActiveRequestCount(),
900
+ status: this.status
890
901
  });
891
902
  });
892
903
  this.app.get(`${prefix}/client.ts`, async (ctx) => {
@@ -1083,7 +1094,12 @@ var Microservice = class {
1083
1094
  process.on("SIGINT", () => {
1084
1095
  logger_default.info(`
1085
1096
  Received SIGINT signal`);
1086
- this.gracefulShutdown();
1097
+ this.shutdown();
1098
+ });
1099
+ process.on("SIGTERM", () => {
1100
+ logger_default.info(`
1101
+ Received SIGTERM signal`);
1102
+ this.shutdown();
1087
1103
  });
1088
1104
  process.on("unhandledrejection", (event) => {
1089
1105
  logger_default.error("Unhandled rejection:", event.reason);
@@ -1095,14 +1111,16 @@ Received SIGINT signal`);
1095
1111
  /**
1096
1112
  * 优雅停机
1097
1113
  */
1098
- async gracefulShutdown() {
1099
- if (this.isShuttingDown) return;
1100
- this.isShuttingDown = true;
1101
- logger_default.info("\nGraceful shutdown initiated...");
1114
+ async shutdown() {
1115
+ if (this.status === "shutting_down") return;
1116
+ this.status = "shutting_down";
1117
+ logger_default.info("\nshutdown initiated...");
1102
1118
  if (this.statisticsTimer) clearInterval(this.statisticsTimer);
1103
1119
  try {
1120
+ await this.waitForActiveRequests();
1121
+ await this.executeCleanupHooks();
1104
1122
  await this.stop();
1105
- logger_default.info("Graceful shutdown completed");
1123
+ logger_default.info("shutdown completed");
1106
1124
  } catch (error) {
1107
1125
  logger_default.error("Error during shutdown:", error);
1108
1126
  process.exit(1);
@@ -1110,6 +1128,57 @@ Received SIGINT signal`);
1110
1128
  process.exit(0);
1111
1129
  }
1112
1130
  }
1131
+ /**
1132
+ * 等待所有活跃请求完成
1133
+ */
1134
+ async waitForActiveRequests() {
1135
+ const timeout = this.options.gracefulShutdown?.timeout || 3e4;
1136
+ const startTime = Date.now();
1137
+ logger_default.info(`Waiting for ${this.activeRequests.size} active requests to complete...`);
1138
+ return new Promise((resolve) => {
1139
+ const checkInterval = setInterval(() => {
1140
+ const elapsed = Date.now() - startTime;
1141
+ if (this.activeRequests.size === 0) {
1142
+ clearInterval(checkInterval);
1143
+ logger_default.info("All active requests completed");
1144
+ resolve();
1145
+ } else if (elapsed >= timeout) {
1146
+ clearInterval(checkInterval);
1147
+ logger_default.warn(`Timeout waiting for requests to complete. ${this.activeRequests.size} requests still active`);
1148
+ resolve();
1149
+ } else {
1150
+ logger_default.info(`Still waiting for ${this.activeRequests.size} requests... (${elapsed}ms elapsed)`);
1151
+ }
1152
+ }, 1e3);
1153
+ });
1154
+ }
1155
+ /**
1156
+ * 执行清理hook
1157
+ */
1158
+ async executeCleanupHooks() {
1159
+ const hooks = this.options.gracefulShutdown?.cleanupHooks || [];
1160
+ if (hooks.length === 0) {
1161
+ logger_default.info("No cleanup hooks configured");
1162
+ return;
1163
+ }
1164
+ logger_default.info(`Executing ${hooks.length} cleanup hooks...`);
1165
+ for (const hook of hooks) {
1166
+ try {
1167
+ const timeout = hook.timeout || 5e3;
1168
+ logger_default.info(`Executing cleanup hook: ${hook.name}`);
1169
+ await Promise.race([
1170
+ Promise.resolve(hook.cleanup()),
1171
+ new Promise(
1172
+ (_, reject) => setTimeout(() => reject(new Error(`Cleanup hook ${hook.name} timeout`)), timeout)
1173
+ )
1174
+ ]);
1175
+ logger_default.info(`Cleanup hook ${hook.name} completed successfully`);
1176
+ } catch (error) {
1177
+ logger_default.error(`Cleanup hook ${hook.name} failed:`, error);
1178
+ }
1179
+ }
1180
+ logger_default.info("All cleanup hooks completed");
1181
+ }
1113
1182
  initStatsEventManager() {
1114
1183
  this.statisticsTimer = setInterval(async () => {
1115
1184
  await this.updateStats();
@@ -1151,14 +1220,54 @@ Received SIGINT signal`);
1151
1220
  }
1152
1221
  return handler;
1153
1222
  }
1223
+ /**
1224
+ * 添加活跃请求跟踪
1225
+ */
1226
+ addActiveRequest(requestId, requestInfo) {
1227
+ this.activeRequests.set(requestId, requestInfo);
1228
+ }
1229
+ /**
1230
+ * 移除活跃请求跟踪
1231
+ */
1232
+ removeActiveRequest(requestId) {
1233
+ this.activeRequests.delete(requestId);
1234
+ }
1235
+ /**
1236
+ * 获取当前活跃请求数量
1237
+ */
1238
+ getActiveRequestCount() {
1239
+ return this.activeRequests.size;
1240
+ }
1241
+ /**
1242
+ * 获取当前活跃请求信息
1243
+ */
1244
+ getActiveRequests() {
1245
+ return Array.from(this.activeRequests.values());
1246
+ }
1154
1247
  handleRequest = async (ctx) => {
1155
1248
  const { moduleName, actionName } = ctx.req.param();
1156
1249
  const handler = this.getActionHandler(moduleName, actionName);
1250
+ const requestId = crypto.randomUUID();
1251
+ const startTime = Date.now();
1252
+ if (this.status === "shutting_down") {
1253
+ return ctx.json({
1254
+ success: false,
1255
+ error: "Service is shutting down"
1256
+ }, 503);
1257
+ }
1157
1258
  try {
1158
1259
  const paramsText = await ctx.req.text();
1260
+ this.addActiveRequest(requestId, {
1261
+ id: requestId,
1262
+ moduleName,
1263
+ actionName,
1264
+ startTime,
1265
+ params: paramsText
1266
+ });
1159
1267
  const result = await handler.handle(paramsText);
1160
1268
  if (handler.metadata.stream) {
1161
1269
  const encoder = new TextEncoder();
1270
+ const microservice = this;
1162
1271
  const stream = new ReadableStream({
1163
1272
  async start(controller) {
1164
1273
  try {
@@ -1182,6 +1291,8 @@ Received SIGINT signal`);
1182
1291
  encoder.encode(ejson4.stringify(response) + "\n")
1183
1292
  );
1184
1293
  controller.close();
1294
+ } finally {
1295
+ microservice.removeActiveRequest(requestId);
1185
1296
  }
1186
1297
  }
1187
1298
  });
@@ -1193,8 +1304,10 @@ Received SIGINT signal`);
1193
1304
  }
1194
1305
  });
1195
1306
  }
1307
+ this.removeActiveRequest(requestId);
1196
1308
  return ctx.text(ejson4.stringify({ success: true, data: result }));
1197
1309
  } catch (error) {
1310
+ this.removeActiveRequest(requestId);
1198
1311
  return ctx.json({ success: false, error: error.message });
1199
1312
  }
1200
1313
  };