import type { RunResult } from "../types"; import { getRunnerStrategy } from "../config/runnerStrategies"; /** * 代码运行引擎 * 使用策略模式支持多种语言 */ export class CodeRunner { private timeout: number; private abortController: AbortController | null = null; constructor(timeout: number = 5000) { this.timeout = timeout; } /** * 运行代码 */ async run( code: string, language: string, testCases?: import("../types").TestCase[], ): Promise { // 获取对应语言的运行策略 const strategy = getRunnerStrategy(language); if (!strategy) { return { output: "", error: `语言 "${language}" 不支持运行`, executionTime: 0, status: "error", }; } // 创建超时控制 this.abortController = new AbortController(); const timeoutId = setTimeout(() => { this.abortController?.abort(); }, this.timeout); try { // 执行代码 const result = await Promise.race([ strategy(code, testCases), this.createTimeoutPromise(), ]); clearTimeout(timeoutId); return result; } catch (error: any) { clearTimeout(timeoutId); if (error.name === "AbortError") { return { output: "", error: `执行超时(${this.timeout}ms)`, executionTime: this.timeout, status: "timeout", }; } return { output: "", error: error.message || String(error), executionTime: 0, status: "error", }; } finally { this.abortController = null; } } /** * 创建超时 Promise */ private createTimeoutPromise(): Promise { return new Promise((_, reject) => { this.abortController?.signal.addEventListener("abort", () => { const error = new Error("Execution timeout"); error.name = "AbortError"; reject(error); }); }); } /** * 取消运行 */ cancel(): void { this.abortController?.abort(); } /** * 设置超时时间 */ setTimeout(timeout: number): void { this.timeout = timeout; } /** * 销毁 */ destroy(): void { this.cancel(); } }