From 2b39135c634d13b4ae7817319514820654752427 Mon Sep 17 00:00:00 2001 From: jinchao <383321154@qq.com> Date: Wed, 14 May 2025 16:11:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E5=BC=95=E6=93=8E?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E8=AF=BB=E5=8F=96log=E7=9A=84?= =?UTF-8?q?=E5=A4=9A=E4=BD=99=E7=9A=84tail=E8=BF=9B=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Release/database/XNSim.db | Bin 200704 -> 200704 bytes XNSimHtml/components/run-simulation.js | 23 ++++++++ XNSimHtml/routes/run-simulation.js | 77 ++++++++++++------------- 3 files changed, 61 insertions(+), 39 deletions(-) diff --git a/Release/database/XNSim.db b/Release/database/XNSim.db index 3ee549cf7175f727d964cc6a99c95937c396fe0f..031aa438dcbf65c4587e5083dca75a2f476d59dc 100644 GIT binary patch delta 77 zcmZozz|*jRXM!~2vxzd!jL#YqS`!#s6PUIpFi+=W+FUyQCm*w&vY~;Ip@o6DiC#{A hx{-mAsjh*kuAxbYfrXW!ft8`9o}rQH^eBGjWdPW&7PkNZ delta 77 zcmZozz|*jRXM!~2qlq%kjE@= { + console.error('清理仿真资源失败:', error); + }); + } + this.eventSource.close(); this.eventSource = null; } @@ -1052,6 +1061,20 @@ class RunSimulation extends HTMLElement { this.resetUIAfterCompletion(); } } + + // 添加组件销毁时的清理方法 + disconnectedCallback() { + // 清理SSE连接和相关资源 + this.closeEventSource(); + + // 重置所有状态 + this.currentSimulationId = null; + this.reconnectAttempts = 0; + this.scenarioFiles = []; + this.currentScenario = null; + this.modelGroups = []; + this.services = []; + } } customElements.define('run-simulation', RunSimulation); \ No newline at end of file diff --git a/XNSimHtml/routes/run-simulation.js b/XNSimHtml/routes/run-simulation.js index f973f67..c176b77 100644 --- a/XNSimHtml/routes/run-simulation.js +++ b/XNSimHtml/routes/run-simulation.js @@ -123,26 +123,27 @@ router.get('/simulation-output/:id', async (req, res) => { }); // 将进程添加到runningSimulations - runningSimulations.set(simulationId, { + const simulation = runningSimulations.get(simulationId) || { pid: processInfo.pid, startTime: new Date(processInfo.start_time).getTime(), output: '', errorOutput: '', logFile: processInfo.log_file - }); + }; + runningSimulations.set(simulationId, simulation); // 使用tail命令来跟踪日志文件 const tailProcess = spawn('tail', ['-f', processInfo.log_file], { stdio: ['ignore', 'pipe', 'pipe'] }); + // 保存tail进程引用 + simulation.tailProcess = tailProcess; + // 收集标准输出 tailProcess.stdout.on('data', (data) => { const chunk = data.toString('utf8'); - const simulation = runningSimulations.get(simulationId); - if (simulation) { - simulation.output += chunk; - } + simulation.output += chunk; // 推送到SSE客户端 sendSSEMessage(simulationId, 'output', { @@ -153,11 +154,17 @@ router.get('/simulation-output/:id', async (req, res) => { // 当客户端断开连接时清理 req.on('close', () => { - tailProcess.kill(); + if (simulation.tailProcess) { + simulation.tailProcess.kill(); + simulation.tailProcess = null; + } }); // 当tail进程结束时 tailProcess.on('close', (code) => { + if (simulation.tailProcess === tailProcess) { + simulation.tailProcess = null; + } runningSimulations.delete(simulationId); sendSSEMessage(simulationId, 'status', { running: false, @@ -316,7 +323,7 @@ router.post('/run-simulation', async (req, res) => { scenario_file: args[0] }); - // 保存到运行中的仿真Map + // 保存到运行中的仿真Map,但不启动tail进程 runningSimulations.set(simulationId, { pid: processId, startTime: Date.now(), @@ -332,37 +339,6 @@ router.post('/run-simulation', async (req, res) => { simulationId: processId.toString(), scenarioFile: args[0] }); - - // 启动一个后台任务来监控日志文件 - const tailProcess = spawn('tail', ['-f', logFile], { - stdio: ['ignore', 'pipe', 'pipe'] - }); - - // 收集输出 - tailProcess.stdout.on('data', (data) => { - const chunk = data.toString('utf8'); - const simulation = runningSimulations.get(simulationId); - if (simulation) { - simulation.output += chunk; - } - - // 推送到SSE客户端 - sendSSEMessage(simulationId, 'output', { - type: 'stdout', - data: chunk - }); - }); - - // 当tail进程结束时 - tailProcess.on('close', (code) => { - runningSimulations.delete(simulationId); - // 删除数据库中的进程记录 - deleteXNEngineProcess(processId); - sendSSEMessage(simulationId, 'status', { - running: false, - message: '仿真进程已结束' - }); - }); } else { // 进程启动失败或不是XNEngine进程 await deleteXNEngineProcess(processId); @@ -500,4 +476,27 @@ router.get('/check-xnengine', async (req, res) => { } }); +// 添加清理仿真资源的接口 +router.post('/cleanup-simulation/:id', (req, res) => { + const simulationId = req.params.id; + + // 清理该仿真ID对应的所有资源 + if (runningSimulations.has(simulationId)) { + // 清理tail进程 + const simulation = runningSimulations.get(simulationId); + if (simulation.tailProcess) { + try { + simulation.tailProcess.kill(); + } catch (error) { + console.error('清理tail进程失败:', error); + } + } + + // 清理其他资源 + runningSimulations.delete(simulationId); + } + + res.json({ success: true, message: '仿真资源已清理' }); +}); + module.exports = router; \ No newline at end of file