imean-service-engine 1.5.0 → 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
@@ -779,10 +779,11 @@ var Microservice = class {
779
779
  lease;
780
780
  scheduler;
781
781
  abortController;
782
- isShuttingDown = false;
783
782
  statisticsTimer;
784
783
  wsHandler;
785
784
  actionHandlers = /* @__PURE__ */ new Map();
785
+ activeRequests = /* @__PURE__ */ new Map();
786
+ status = "running";
786
787
  modules = /* @__PURE__ */ new Map();
787
788
  fetch;
788
789
  options;
@@ -805,6 +806,10 @@ var Microservice = class {
805
806
  websocket: { enabled: false },
806
807
  cacheAdapter: new MemoryCacheAdapter(),
807
808
  plugins: [],
809
+ gracefulShutdown: {
810
+ timeout: 3e4,
811
+ cleanupHooks: []
812
+ },
808
813
  ...options
809
814
  };
810
815
  this.cache = this.options.cacheAdapter;
@@ -883,7 +888,7 @@ var Microservice = class {
883
888
  this.app.get(prefix, (ctx) => {
884
889
  const name = this.options.name ?? "Microservice";
885
890
  const version = this.options.version ?? "1.0.0";
886
- return ctx.text(`${name} is running. version: ${version}`);
891
+ return ctx.text(`${name} is ${this.status}. version: ${version}`);
887
892
  });
888
893
  this.app.get(`${prefix}/health`, (ctx) => {
889
894
  return ctx.json({
@@ -899,7 +904,9 @@ var Microservice = class {
899
904
  version: this.options.version,
900
905
  env: this.options.env,
901
906
  modules: this.getModules(),
902
- stats: Object.fromEntries(this.statsMap)
907
+ stats: Object.fromEntries(this.statsMap),
908
+ activeRequests: this.getActiveRequestCount(),
909
+ status: this.status
903
910
  });
904
911
  });
905
912
  this.app.get(`${prefix}/client.ts`, async (ctx) => {
@@ -1096,7 +1103,12 @@ var Microservice = class {
1096
1103
  process.on("SIGINT", () => {
1097
1104
  logger_default.info(`
1098
1105
  Received SIGINT signal`);
1099
- this.gracefulShutdown();
1106
+ this.shutdown();
1107
+ });
1108
+ process.on("SIGTERM", () => {
1109
+ logger_default.info(`
1110
+ Received SIGTERM signal`);
1111
+ this.shutdown();
1100
1112
  });
1101
1113
  process.on("unhandledrejection", (event) => {
1102
1114
  logger_default.error("Unhandled rejection:", event.reason);
@@ -1108,14 +1120,16 @@ Received SIGINT signal`);
1108
1120
  /**
1109
1121
  * 优雅停机
1110
1122
  */
1111
- async gracefulShutdown() {
1112
- if (this.isShuttingDown) return;
1113
- this.isShuttingDown = true;
1114
- 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...");
1115
1127
  if (this.statisticsTimer) clearInterval(this.statisticsTimer);
1116
1128
  try {
1129
+ await this.waitForActiveRequests();
1130
+ await this.executeCleanupHooks();
1117
1131
  await this.stop();
1118
- logger_default.info("Graceful shutdown completed");
1132
+ logger_default.info("shutdown completed");
1119
1133
  } catch (error) {
1120
1134
  logger_default.error("Error during shutdown:", error);
1121
1135
  process.exit(1);
@@ -1123,6 +1137,57 @@ Received SIGINT signal`);
1123
1137
  process.exit(0);
1124
1138
  }
1125
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
+ }
1126
1191
  initStatsEventManager() {
1127
1192
  this.statisticsTimer = setInterval(async () => {
1128
1193
  await this.updateStats();
@@ -1164,14 +1229,54 @@ Received SIGINT signal`);
1164
1229
  }
1165
1230
  return handler;
1166
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
+ }
1167
1256
  handleRequest = async (ctx) => {
1168
1257
  const { moduleName, actionName } = ctx.req.param();
1169
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
+ }
1170
1267
  try {
1171
1268
  const paramsText = await ctx.req.text();
1269
+ this.addActiveRequest(requestId, {
1270
+ id: requestId,
1271
+ moduleName,
1272
+ actionName,
1273
+ startTime,
1274
+ params: paramsText
1275
+ });
1172
1276
  const result = await handler.handle(paramsText);
1173
1277
  if (handler.metadata.stream) {
1174
1278
  const encoder = new TextEncoder();
1279
+ const microservice = this;
1175
1280
  const stream = new ReadableStream({
1176
1281
  async start(controller) {
1177
1282
  try {
@@ -1195,6 +1300,8 @@ Received SIGINT signal`);
1195
1300
  encoder.encode(ejson4__default.default.stringify(response) + "\n")
1196
1301
  );
1197
1302
  controller.close();
1303
+ } finally {
1304
+ microservice.removeActiveRequest(requestId);
1198
1305
  }
1199
1306
  }
1200
1307
  });
@@ -1206,8 +1313,10 @@ Received SIGINT signal`);
1206
1313
  }
1207
1314
  });
1208
1315
  }
1316
+ this.removeActiveRequest(requestId);
1209
1317
  return ctx.text(ejson4__default.default.stringify({ success: true, data: result }));
1210
1318
  } catch (error) {
1319
+ this.removeActiveRequest(requestId);
1211
1320
  return ctx.json({ success: false, error: error.message });
1212
1321
  }
1213
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
@@ -770,10 +770,11 @@ var Microservice = class {
770
770
  lease;
771
771
  scheduler;
772
772
  abortController;
773
- isShuttingDown = false;
774
773
  statisticsTimer;
775
774
  wsHandler;
776
775
  actionHandlers = /* @__PURE__ */ new Map();
776
+ activeRequests = /* @__PURE__ */ new Map();
777
+ status = "running";
777
778
  modules = /* @__PURE__ */ new Map();
778
779
  fetch;
779
780
  options;
@@ -796,6 +797,10 @@ var Microservice = class {
796
797
  websocket: { enabled: false },
797
798
  cacheAdapter: new MemoryCacheAdapter(),
798
799
  plugins: [],
800
+ gracefulShutdown: {
801
+ timeout: 3e4,
802
+ cleanupHooks: []
803
+ },
799
804
  ...options
800
805
  };
801
806
  this.cache = this.options.cacheAdapter;
@@ -874,7 +879,7 @@ var Microservice = class {
874
879
  this.app.get(prefix, (ctx) => {
875
880
  const name = this.options.name ?? "Microservice";
876
881
  const version = this.options.version ?? "1.0.0";
877
- return ctx.text(`${name} is running. version: ${version}`);
882
+ return ctx.text(`${name} is ${this.status}. version: ${version}`);
878
883
  });
879
884
  this.app.get(`${prefix}/health`, (ctx) => {
880
885
  return ctx.json({
@@ -890,7 +895,9 @@ var Microservice = class {
890
895
  version: this.options.version,
891
896
  env: this.options.env,
892
897
  modules: this.getModules(),
893
- stats: Object.fromEntries(this.statsMap)
898
+ stats: Object.fromEntries(this.statsMap),
899
+ activeRequests: this.getActiveRequestCount(),
900
+ status: this.status
894
901
  });
895
902
  });
896
903
  this.app.get(`${prefix}/client.ts`, async (ctx) => {
@@ -1087,7 +1094,12 @@ var Microservice = class {
1087
1094
  process.on("SIGINT", () => {
1088
1095
  logger_default.info(`
1089
1096
  Received SIGINT signal`);
1090
- this.gracefulShutdown();
1097
+ this.shutdown();
1098
+ });
1099
+ process.on("SIGTERM", () => {
1100
+ logger_default.info(`
1101
+ Received SIGTERM signal`);
1102
+ this.shutdown();
1091
1103
  });
1092
1104
  process.on("unhandledrejection", (event) => {
1093
1105
  logger_default.error("Unhandled rejection:", event.reason);
@@ -1099,14 +1111,16 @@ Received SIGINT signal`);
1099
1111
  /**
1100
1112
  * 优雅停机
1101
1113
  */
1102
- async gracefulShutdown() {
1103
- if (this.isShuttingDown) return;
1104
- this.isShuttingDown = true;
1105
- 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...");
1106
1118
  if (this.statisticsTimer) clearInterval(this.statisticsTimer);
1107
1119
  try {
1120
+ await this.waitForActiveRequests();
1121
+ await this.executeCleanupHooks();
1108
1122
  await this.stop();
1109
- logger_default.info("Graceful shutdown completed");
1123
+ logger_default.info("shutdown completed");
1110
1124
  } catch (error) {
1111
1125
  logger_default.error("Error during shutdown:", error);
1112
1126
  process.exit(1);
@@ -1114,6 +1128,57 @@ Received SIGINT signal`);
1114
1128
  process.exit(0);
1115
1129
  }
1116
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
+ }
1117
1182
  initStatsEventManager() {
1118
1183
  this.statisticsTimer = setInterval(async () => {
1119
1184
  await this.updateStats();
@@ -1155,14 +1220,54 @@ Received SIGINT signal`);
1155
1220
  }
1156
1221
  return handler;
1157
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
+ }
1158
1247
  handleRequest = async (ctx) => {
1159
1248
  const { moduleName, actionName } = ctx.req.param();
1160
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
+ }
1161
1258
  try {
1162
1259
  const paramsText = await ctx.req.text();
1260
+ this.addActiveRequest(requestId, {
1261
+ id: requestId,
1262
+ moduleName,
1263
+ actionName,
1264
+ startTime,
1265
+ params: paramsText
1266
+ });
1163
1267
  const result = await handler.handle(paramsText);
1164
1268
  if (handler.metadata.stream) {
1165
1269
  const encoder = new TextEncoder();
1270
+ const microservice = this;
1166
1271
  const stream = new ReadableStream({
1167
1272
  async start(controller) {
1168
1273
  try {
@@ -1186,6 +1291,8 @@ Received SIGINT signal`);
1186
1291
  encoder.encode(ejson4.stringify(response) + "\n")
1187
1292
  );
1188
1293
  controller.close();
1294
+ } finally {
1295
+ microservice.removeActiveRequest(requestId);
1189
1296
  }
1190
1297
  }
1191
1298
  });
@@ -1197,8 +1304,10 @@ Received SIGINT signal`);
1197
1304
  }
1198
1305
  });
1199
1306
  }
1307
+ this.removeActiveRequest(requestId);
1200
1308
  return ctx.text(ejson4.stringify({ success: true, data: result }));
1201
1309
  } catch (error) {
1310
+ this.removeActiveRequest(requestId);
1202
1311
  return ctx.json({ success: false, error: error.message });
1203
1312
  }
1204
1313
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imean-service-engine",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "microservice engine",
5
5
  "keywords": [
6
6
  "microservice",