Skip to content

fix: follow up on router autostart and supervisor lifecycle - #20

Open
LeaningLearner wants to merge 1 commit into
fish2lab:mainfrom
LeaningLearner:LeaningLearner/fix-windows-router-autostart
Open

fix: follow up on router autostart and supervisor lifecycle#20
LeaningLearner wants to merge 1 commit into
fish2lab:mainfrom
LeaningLearner:LeaningLearner/fix-windows-router-autostart

Conversation

@LeaningLearner

Copy link
Copy Markdown
Contributor

背景

这是上一次 DSCodex 路由器自动启动和生命周期管理相关 PR 的后续补充修复。

上一次 PR 合入后,进一步进行了代码审查、并发测试和故障注入测试,发现 supervisor 所有权识别、崩溃退避期间停止、自动启动失败回滚以及 Windows 任务计划程序清理等场景仍存在边界问题。

本 PR 不改变 DSCodex 的核心路由行为,主要增强路由器监督机制和跨平台自动启动功能在异常情况下的可靠性。

概述

增强 DSCodex 路由器 supervisor 和各平台自动启动功能,重点处理以下场景:

  • supervisor 状态文件已经过期,但其中的 PID 被其他进程复用;
  • 路由器崩溃后,supervisor 正处于重启退避等待期间;
  • 多个 supervisor 实例同时尝试取得控制权;
  • 文件系统不支持硬链接;
  • 自动启动注册或替换进行到一半时失败;
  • PID 状态文件缺失、损坏或被其他实例替换;
  • 禁用自动启动或卸载时,某个清理步骤失败。

目标是确保 DSCodex 可以可靠识别当前 supervisor 实例、安全停止路由器,并在自动启动配置失败时恢复原有运行状态。

主要变更

Supervisor 所有权与实例认证

  • 新增经过认证且按实例代际隔离的 supervisor 所有权机制。
  • 每个 supervisor 实例使用独立的实例 ID 和随机认证令牌。
  • 通过质询—响应机制确认 supervisor 是否仍然拥有当前控制权。
  • 不再仅根据 PID 是否存活判断 supervisor 状态。
  • 防止 PID 被系统复用后,无关进程被误判为 DSCodex supervisor。
  • 防止过期状态文件阻止新的 supervisor 实例启动。
  • 防止旧 supervisor 在退出清理时删除新实例发布的状态。

崩溃恢复与安全停止

  • 允许 stop 在路由器崩溃后的重启退避期间取消 supervisor。
  • supervisor 在启动子进程前、子进程退出后以及退避等待期间持续检查停止请求。
  • 停止请求与具体 supervisor 实例绑定,旧请求不会影响后续启动的新实例。
  • 失去所有权的 supervisor 会停止自己持有的子进程,不会根据磁盘中的 PID 向未知进程发送信号。
  • 保持经过认证的 HTTP 关闭流程,避免终止未验证或 PID 已被复用的进程。
  • supervisor 正常关闭后不会再次启动路由器。

文件系统兼容性

  • 移除 supervisor 所有权机制对文件系统硬链接的依赖。
  • 使用原子控制目录和实例状态完成所有权竞争与状态发布。
  • 支持不允许创建硬链接或返回 EPERMENOTSUP 的文件系统。
  • 并发启动多个 supervisor 时,只允许一个实例成为有效所有者。

跨平台自动启动回滚

  • 增强 macOS launchd、Linux systemd 和 Windows 任务计划程序启用失败时的回滚流程。
  • 自动启动注册失败时,尽可能恢复此前健康运行的手动路由器。
  • 避免在自动启动管理器尚未真正接管前错误停止原有实例。
  • 回滚过程中会停止本次操作新启动的托管实例,避免留下后台进程。
  • 将自动启动管理器、生成文件和运行实例视为独立状态分别恢复。

Windows 任务计划程序

  • Windows 任务替换失败时,保留原有任务及其 VBS 启动器。
  • 在注册新任务前保存原有任务和启动器状态。
  • 新任务启动后再验证实际运行状态。
  • 修复没有旧路由器时,新任务启动成功但后续验证失败所造成的实例残留。
  • 改进 PID 状态文件缺失或损坏时的禁用和卸载处理。
  • 保持 VBS 隐藏启动方式以及任务计划程序的二级崩溃恢复设置。

禁用与卸载清理

  • 自动启动禁用和卸载改为尽力执行全部清理步骤。
  • 某个步骤失败时,不会立即跳过其余清理操作。
  • 依次尝试停止托管实例、撤销平台自动启动管理器、删除生成文件并清理配置。
  • 最终汇总所有清理错误,便于诊断部分失败。
  • 避免单个损坏的 PID 状态文件阻止其余卸载流程。

Catalog 就绪检查

  • 新增模型目录就绪检查。
  • 安装流程和 doctor 可以确认 DeepSeek V4 Flash 与 Pro 条目是否存在。
  • 检查模型 slug、基础指令以及当前必需字段的基本结构。
  • 避免仅凭 catalog 文件存在就错误报告目录状态正常。

依赖锁文件

  • 新增 package-lock.json
  • 将根软件包及锁文件中的版本统一为 1.1.0
  • 避免提交仍标记旧版本 0.6.0 的锁文件。

测试覆盖

新增和扩展的测试覆盖以下场景:

  • supervisor 在崩溃退避期间收到停止请求;
  • supervisor PID 已被其他活跃进程复用;
  • 多个 supervisor 并发争夺所有权;
  • 文件系统创建硬链接时返回 EPERMENOTSUP
  • 旧 supervisor 延迟清理时存在新的替代实例;
  • supervisor 崩溃后遗留状态和停止请求;
  • Windows 自动启动注册失败后的手动路由器恢复;
  • Windows 任务替换失败时保留原任务和 VBS 文件;
  • Windows 新任务启动后验证失败时的回滚;
  • PID 状态损坏时继续执行禁用和卸载清理;
  • 路由器状态被替代实例并发更新;
  • Catalog 缺少模型、字段类型错误或 slug 重复。

验证结果

执行:

npm test

结果:

  • 共 110 项测试;
  • 109 项通过;
  • 1 项 Windows 信号处理测试按预期跳过;
  • 0 项失败。

同时执行:

git diff --check

检查通过,没有发现空白字符错误。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant