SuperAPI AI 工具集

fleet-stop

部署与运维

查看项目

更新于 10-23 23:07

技能介绍

用途

fleet-stop 用于终止一次 CocoFleet 运行中的所有正在运行的进程。它会向每个实例发送 SIGTERM 信号,等待最多 10 秒进行优雅关闭,若进程仍未退出则发送 SIGKILL 强制终止,并更新状态文件、生成停止记录。

主要能力

  • 检查 .cocoplus/ 目录是否存在,未初始化时给出提示并停止。
  • 解析参数 $fleet stop [fleet-id],缺少 fleet-id 时输出用法提示并停止。
  • 读取 .cocoplus/fleet/[fleet-id]-state.json,找不到时输出提示并停止。
  • 对状态为 running 的每个实例,从 state.json 读取 PID,通过 Bash 工具调用跨平台 Node.js 发送 SIGTERM。
  • 最多等待 10 秒进行优雅关闭,每秒检查一次进程存活状态;超时后发送 SIGKILL。
  • 更新 state.json:将状态设为 stopped,并记录 completed_at 时间戳。
  • 写入 .cocoplus/fleet/[fleet-id]-stop-record.md 停止记录,包含 Fleet ID、停止时间以及每个已停止实例的表格(实例、最后状态、最后检查点、PID)。
  • 输出停止结果摘要,包括终止的进程数量和停止记录路径。

使用方式

命令格式:$fleet stop [fleet-id]

执行流程:

  1. 验证 .cocoplus/ 是否存在,否则输出 "CocoPlus not initialized in this directory. Run $pod init to begin." 并停止。
  2. 解析 fleet-id,若缺失则输出 "Usage: $fleet stop [fleet-id]" 并停止。
  3. 读取 .cocoplus/fleet/[fleet-id]-state.json,若不存在则输出 "Fleet state not found for [fleet-id]." 并停止。
  4. 对每个 running 实例,读取 PID 并发送 SIGTERM: node -e "try{process.kill([pid],'SIGTERM')}catch(e){}"
  5. 等待最多 10 秒,每秒检查存活,超时后发送 SIGKILL: node -e " const pid=[pid]; let waited=0; const iv=setInterval(()=>{ try{process.kill(pid,0);waited++;} catch(e){clearInterval(iv);} if(waited>=10){try{process.kill(pid,'SIGKILL')}catch(_){}clearInterval(iv);} },1000);"
  6. 更新 state.json:status = "stopped",completed_at = [timestamp]。
  7. 写入停止记录文件 .cocoplus/fleet/[fleet-id]-stop-record.md。
  8. 输出:"Fleet [fleet-id] stopped. [N] processes terminated. Stop record: .cocoplus/fleet/[fleet-id]-stop-record.md."

适用场景

  • 需要安全、可审计地停止整个 CocoFleet 运行。
  • 需要确保所有相关进程被终止,避免遗留孤儿进程或日志文件。
  • 需要留下停止记录作为审计证据,记录何时以及为何停止。

限制与注意事项

  • 必须在已初始化 CocoPlus 的目录中运行(存在 .cocoplus/)。
  • 必须提供有效的 fleet-id,且对应的状态文件存在。
  • 不应在发送信号前更新 state.json,状态必须反映真实情况,只有确认进程死亡后才标记为 stopped。
  • 不应跳过 SIGTERM 超时后的 SIGKILL,否则忽略 SIGTERM 的进程会继续运行并产生孤儿日志文件。
  • 不应跳过停止记录,否则缺少停止时间和原因的追踪。

退出标准

  • 所有先前处于 running 状态的实例在 .cocoplus/fleet/[fleet-id]-state.json 中状态变为 stopped。
  • .cocoplus/fleet/[fleet-id]-stop-record.md 存在并列出已停止实例。
  • 该 fleet 的所有 PID 均不再存活(通过 node -e "process.kill([pid],0)" 返回错误验证)。