| 2386 | |
| 2387 | class TimeoutMiddleware implements Middleware { |
| 2388 | private configManagerPromise: Promise<ConfigManager>; |
| 2389 | |
| 2390 | constructor(configManagerPromise: Promise<ConfigManager>) { |
| 2391 | this.configManagerPromise = configManagerPromise; |
| 2392 | } |
| 2393 | |
| 2394 | async process<T>( |
| 2395 | input: T, |
| 2396 | next: (input: T, token?: AbortToken) => Promise<any>, |
| 2397 | token?: AbortToken, |
| 2398 | ): Promise<any> { |
| 2399 | const config = (await this.configManagerPromise).getConfig(); |
| 2400 | const timeoutMs = config.timeout * 1000; |
| 2401 | |
| 2402 | const timeoutController = new AbortController(); |
| 2403 | const timeoutId = setTimeout( |
| 2404 | () => timeoutController.abort(`请求超时: ${timeoutMs}ms`), |
| 2405 | timeoutMs, |
| 2406 | ); |
| 2407 | |
| 2408 | try { |
| 2409 | const combined = this.combine(timeoutController, token); |
| 2410 | combined.signal.addEventListener("abort", () => clearTimeout(timeoutId), { |
| 2411 | once: true, |
| 2412 | }); |
| 2413 | return await next(input, combined); |
| 2414 | } finally { |
| 2415 | clearTimeout(timeoutId); |
| 2416 | } |
| 2417 | } |
| 2418 | |
| 2419 | private combine( |
| 2420 | timeoutController: AbortController, |
| 2421 | externalToken?: AbortToken, |
| 2422 | ): AbortToken { |
| 2423 | const controller = new AbortController(); |
| 2424 | |
| 2425 | if (timeoutController.signal.aborted) |
| 2426 | controller.abort(timeoutController.signal.reason); |
| 2427 | else |
| 2428 | timeoutController.signal.addEventListener( |
| 2429 | "abort", |
| 2430 | () => controller.abort(timeoutController.signal.reason), |
| 2431 | { |
| 2432 | once: true, |
| 2433 | }, |
| 2434 | ); |
| 2435 | |
| 2436 | if (externalToken) { |
| 2437 | if (externalToken.aborted) controller.abort(externalToken.reason); |
| 2438 | else |
| 2439 | externalToken.signal.addEventListener( |
| 2440 | "abort", |
| 2441 | () => controller.abort(externalToken.reason), |
| 2442 | { |
| 2443 | once: true, |
| 2444 | }, |
| 2445 | ); |
nothing calls this directly
no outgoing calls
no test coverage detected