You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中限制重复分析请求及终止分析的实现方案咨询

Node.js 游戏分析任务:防重复请求与终止方案

一、阻止同一游戏的重复分析请求

用全局Map跟踪当前运行的任务是可行的方案,比数组/普通对象更安全(避免原型链污染)、操作更便捷。每个游戏名称对应一个包含终止控制器和运行状态的对象,路由请求时先检查Map状态:

// 全局任务跟踪容器,key=游戏名称,value={ controller: AbortController, isRunning: boolean }
const runningTasks = new Map();

app.get('/analyzeGame/:name', async (req, res) => {
  const gameName = req.params.name;
  
  // 检查是否已有正在运行的同游戏任务
  const existingTask = runningTasks.get(gameName);
  if (existingTask?.isRunning) {
    return res.send(`游戏 ${gameName} 正在分析中,请稍后再试`);
  }

  // 创建终止控制器,标记任务为运行中
  const controller = new AbortController();
  runningTasks.set(gameName, { controller, isRunning: true });

  // 立即返回响应,不等待分析完成
  res.send(`starting to analyze ${gameName}`);

  // 后台执行分析任务
  try {
    await analyzeGame(gameName, controller.signal);
  } catch (err) {
    if (err.name === 'AbortError') {
      console.log(`游戏 ${gameName} 分析任务已终止`);
    } else {
      console.error(`分析游戏 ${gameName} 出错:`, err);
    }
  } finally {
    // 任务结束(成功/失败/终止),从Map中移除
    runningTasks.delete(gameName);
  }
});

二、终止正在执行的分析任务

通过AbortController实现任务终止,配合/stopAnalyzing/:name路由触发终止信号,同时要求分析函数在关键步骤检查终止状态:

1. 终止路由实现

app.get('/stopAnalyzing/:name', (req, res) => {
  const gameName = req.params.name;
  const task = runningTasks.get(gameName);

  if (!task || !task.isRunning) {
    return res.send(`游戏 ${gameName} 没有正在运行的分析任务`);
  }

  // 触发终止信号,标记任务为已停止
  task.controller.abort();
  task.isRunning = false;
  res.send(`已终止游戏 ${gameName} 的分析任务`);
});

2. 支持终止的分析函数

分析函数需要在耗时步骤(循环、异步操作前)检查终止信号,收到信号后立即停止执行并清理资源:

async function analyzeGame(gameName, signal) {
  // 初始检查:若已终止直接抛出错误
  if (signal.aborted) throw new Error('AbortError');

  // 监听终止事件,执行资源清理
  signal.addEventListener('abort', () => {
    console.log(`终止游戏 ${gameName} 分析,开始清理资源`);
    // 这里可以添加关闭数据库连接、释放临时文件等逻辑
  });

  // 模拟耗时分析流程
  const gameData = await fetchGameRawData(gameName);
  for (const playerData of gameData) {
    // 每处理一个玩家前检查终止状态
    if (signal.aborted) throw new Error('AbortError');
    
    await analyzePlayerData(playerData);
  }

  // 分析完成后存储结果
  await saveAnalysisToDB(gameName, finalResult);
}

关于全局变量的补充说明

  • 单进程Node.js服务中,用Map完全可靠,是轻量高效的方案;
  • 如果是多进程(cluster模式)或分布式部署,全局Map无法跨进程共享,此时需要用Redis等外部存储:用键值对跟踪任务状态,用发布订阅模式传递终止指令。

内容的提问来源于stack exchange,提问作者user13674310

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 19:28:11