8.5 KiB
8.5 KiB
RRPP Lite 模块拆分计划
目标与边界
将当前 main.py(约 3,480 行)渐进拆成职责清晰、可独立测试的模块,同时保持以下行为不变:
- PAC、全局代理、智能分流和本地 TLS 转发的现有接口与优先级;
- 节点订阅、DPAPI 加密存储、登录及本地运行数据位置;
- 源码运行、PyInstaller 单文件版和 Nuitka 版的启动方式;
- 现有
lite/test/test_pac_routing.py的全部回归用例。
本轮拆分期间不提交、不推送到主仓库、不打包发布。每个阶段均只在本地工作区验证;出现回归时优先回退到拆分前备份。
开始前的保护措施
-
记录当前 Git 状态与当前 HEAD,不触碰既有未跟踪的构建产物、备份和用户文件。
-
在
lite/backups/创建带时间戳的源码备份,例如:proxy_lite.py.bak_YYYYMMDD_HHMMSS_before_module_split。 -
首次拆分前运行一次完整基线:
wsl.exe -e bash -lc "cd '/mnt/d/Royirin Rosmontis Private Proxy' && python3 -m py_compile lite/main.py lite/test/test_pac_routing.py && python3 lite/test/test_pac_routing.py" -
每完成一个阶段,先做编译检查,再跑完整 PAC 回归;不通过则在进入下一阶段前修复或回退。
当前实施进度(2026-09-16)
- 已创建拆分前备份:
lite/backups/proxy_lite.py.bak_20260916_220240_before_module_split。 - 已完成一次拆分前基线与多次拆分后全量 PAC 回归。
- UI 主题、控件和三个对话框已迁入
rrpp_ui/theme.py、rrpp_ui/widgets.py、rrpp_ui/dialogs.py;通过显式服务对象调用业务层,不反向导入入口文件。 - 已迁入核心包的无状态功能:CIDR/Trie 与 PAC 规则解析、PAC 拉取和原子写入、
settings.json原子存储、DPAPI 节点/凭据存储、HTTP 转发报文解析与认证注入、 DNS/私网判断与 TTL 缓存、流量统计、节点认证请求协议。 - 节点同步服务、带缓存的完整路由决策、转发器 socket 生命周期、系统代理注册表控制 和主窗口仍在入口文件,待后续阶段继续迁移。
- 已获得用户授权,在完成构建与验证后执行
git commit、git push和 Release 发布。
目标目录
lite/
├─ main.py # 轻量入口、组装依赖、main
├─ rrpp_core/
│ ├─ __init__.py
│ ├─ runtime.py # 路径、常量、日志与共享运行时上下文
│ ├─ config_store.py # 普通配置、节点、DPAPI 凭据
│ ├─ pac_data.py # PAC 在线数据下载、校验、缓存失效
│ ├─ routing.py # 域名/IP 分流、白名单、CIDR/Trie
│ ├─ forwarder.py # 本地 TLS 转发、HTTP CONNECT、认证注入
│ └─ system_proxy.py # PAC 服务、Windows 系统代理状态
├─ rrpp_ui/
│ ├─ __init__.py
│ ├─ theme.py # UI 色彩与样式常量
│ ├─ widgets.py # NodeLabel、开关、状态点等可复用控件
│ └─ dialogs.py # 登录、白名单、设置对话框
└─ test/
└─ test_pac_routing.py
目录是目标形态,而不是一次性迁移要求。入口已统一为 main.py;测试和构建脚本均以该文件为准。
分阶段实施
阶段 0:基线与备份
- 创建源码备份并保存当前测试输出。
- 核验当前核心测试:PAC 规则优先级、IPv4/IPv6、私网、CONNECT 解析、认证注入、启动连通性校验及其取消流程。
- 产物:可随时恢复的单文件版本;无业务代码变更。
阶段 1:抽取无状态 UI 组件
- 将
NodeLabel、ToggleSwitch、StatusDot及图标辅助逻辑移到rrpp_ui/widgets.py。 - 主窗口继续从原入口导入/调用,保持控件信号、样式和构造参数不变。
- 风险低:不涉及代理线程、注册表或路由决策。
- 验收:
py_compile、PAC 全量测试、一次 Windows GUI 手工启动。
阶段 2:建立共享运行时与配置存储
- 抽取路径常量、配置读写、节点读写、DPAPI 加解密、认证保存和订阅节点同步至
rrpp_core/runtime.py、config_store.py。 - 明确依赖方向:模块不得反向导入 UI;日志通过注入函数或统一运行时上下文提供。
- 保持
%LOCALAPPDATA%\\RRPP、配置文件名、加密格式和节点选择恢复逻辑完全兼容。 - 风险中等:涉及用户已有数据;只做机械迁移,不改变存储格式。
- 验收:现有节点可读取;登录/同步至少做一次人工冒烟;全部自动测试通过。
阶段 3:抽取 PAC 数据与路由引擎
-
将 PAC 数据下载/校验/写入和缓存失效移至
rrpp_core/pac_data.py。 -
将白名单、强制代理、明确直连域名、CIDR、IPv6、DNS 解析、Trie 匹配和直连决策移至
rrpp_core/routing.py。 -
使用显式的
RoutingContext或等价配置对象替代跨模块全局变量;规则优先级必须锁定为:用户白名单 > 强制代理 > 明确直连域名 > LAN/私网 > GeoIP 智能分流 -
风险最高的核心阶段;禁止顺便修改规则语义或远程 PAC 格式。
-
验收:扩充并运行分流回归测试,覆盖 Google/OpenAI/Anthropic、国内直连、IPv6、无 DNS 结果与缓存刷新。
阶段 4:抽取转发器与系统代理控制
- 将流量统计、本地 TLS 监听、CONNECT/绝对 URL 解析、认证注入与连接回退移至
rrpp_core/forwarder.py。 - 将 PAC HTTP 服务、注册表备份/恢复、全局/PAC 开关和陈旧状态清理移至
rrpp_core/system_proxy.py。 - 以明确的 start/stop 生命周期对象管理线程与端口,避免模块级状态互相覆盖。
- 风险中高:涉及注册表和后台线程;本阶段不改变任何系统代理策略。
- 验收:本地端口监听、PAC 开关、全局开关、取消启动、退出清理和重复启停的人工测试;完整回归测试。
阶段 5:抽取对话框与收敛入口
- 将
LoginDialog、WhitelistDialog、SettingsDialog移至rrpp_ui/dialogs.py,MainWindow可保留在入口或迁到rrpp_ui/main_window.py。 main.py收敛为:初始化 DPI/单实例、创建运行时、装配 UI、调用main()。- 保留必要的兼容导出,待构建脚本和测试完全迁移后再移除。
- 验收:源码 GUI 手工走查、全量自动测试、PyInstaller/Nuitka 各做一次仅本地的构建与启动冒烟。
阶段 6:清理与交付前评审
- 删除已确认无引用的兼容层,补齐模块文档和最小单元测试。
- 检查循环导入、隐式全局状态、未关闭线程、路径在冻结环境下的差异。
- 对比拆分前后的 PAC 输出和系统代理状态变更。
- 仅在用户确认后,另行决定提交、推送、打包和发布;它们不属于本次拆分的自动后续动作。
依赖与架构约束
main.py → rrpp_ui → rrpp_core
│ │
└───────────┘(仅通过显式上下文/接口协作)
rrpp_core不依赖 PyQt;这样 PAC 与转发逻辑可在无 GUI 环境测试。- UI 不直接读写注册表、节点文件或 socket;统一通过核心服务对象操作。
- 禁止新的模块级可变全局状态,已有状态在迁移时集中到上下文或生命周期对象。
- 配置、加密和 PAC 文件的文件名、字段、URL 与优先级,在本次重构内视为兼容性契约。
验收清单
- 源码
py_compile通过。 test_pac_routing.py全部通过。- PAC 启动/取消、全局模式、退出恢复系统代理均可用。
- 既有节点和已加密凭据可读取,订阅同步不回退格式。
chatgpt.com、auth.openai.com、claude.ai、Google CDN 仍命中强制代理;国内显式直连规则仍生效。- PyInstaller 与 Nuitka 均已完成本地构建;Release 附件将使用版本化文件名和 SHA-256 校验。
- 发布暂存仅包含本轮源码、测试、构建脚本、图标和模板;构建产物、账号数据和备份文件已排除。
- 待提交、推送并上传 Release 附件。
回滚策略
任一阶段出现无法在当前阶段定位的回归时:停止继续迁移,将该阶段涉及文件恢复到阶段开始前的本地备份或 Git 基线;保留失败现场的测试输出以便定位。不得通过覆盖用户的运行配置、订阅或构建目录来“修复”回归。