Skip to content

Latest commit

 

History

History
329 lines (226 loc) · 8.55 KB

File metadata and controls

329 lines (226 loc) · 8.55 KB

TrendRadar Rust 迁移总体思路

1. 目标定义

本次迁移不是把 Python 项目逐文件翻译成 Rust,而是基于现有项目能力做一次“价值重组”:

  • 保留真正构成产品核心价值的能力
  • 删除历史上为兼容、展示、部署便利而堆积的冗余逻辑
  • 将稳定、可复用、可测试的内核收敛到 Rust
  • 将强依赖第三方生态、变化频繁、收益不高的外层能力延后

最终目标不是“Rust 版本的旧 TrendRadar”,而是“一个更小、更稳、更清晰的 TrendRadar 内核”。

为了让迁移过程后续可以被 AI 和人工稳定切分,当前仓库还维护了几份配套基线文档:

2. 迁移原则

2.1 只迁核心链路

Rust 首版只覆盖主价值闭环:

  1. 读取配置
  2. 抓取热点和 RSS 数据
  3. 统一归一化为内部数据模型
  4. 做过滤、聚合、排序、调度判定
  5. 写入本地存储
  6. 生成结构化输出

只要某个能力不直接服务这条链路,就不默认保留。

2.2 先收敛,再扩展

先做一个功能边界明确、行为稳定的最小 Rust 内核,再考虑 AI、MCP、通知渠道扩张,而不是一开始就追求功能对齐。

2.3 优先迁纯逻辑,延后迁生态集成

最适合迁移的是:

  • 调度逻辑
  • 数据模型
  • 过滤与统计逻辑
  • 本地存储
  • 抓取和解析

不适合第一阶段迁移的是:

  • 多 AI 供应商接入
  • 多通知渠道适配
  • MCP 全量工具集
  • Docker / GitHub Actions / 本地环境分支逻辑

2.4 兼容不是目的

旧配置、旧输出、旧命令行参数可以有选择地兼容,不要求 100% 保持原样。凡是显著增加复杂度但没有明显收益的兼容层,应直接丢弃。

3. 现有项目能力分层判断

基于当前 Python 仓库,能力大致可分成四层:

3.1 核心层

  • 热榜抓取
  • RSS 抓取
  • 统一数据模型
  • 关键词过滤与聚合
  • 排名权重和统计
  • 调度解析
  • 本地存储

这一层应优先迁移,并作为 Rust 项目的主体。

3.2 交付层

  • HTML 报告
  • 结构化 JSON 输出
  • 基础通知推送

这一层只保留最少必要能力,不追求旧项目的所有展示细节。

3.3 集成层

  • MCP Server
  • AI 分析
  • AI 翻译
  • 远程存储
  • 多渠道通知

这一层不应进入 Rust 首版核心范围。

3.4 历史包袱层

  • 自动打开浏览器
  • 版本检查与远程配置版本检查
  • 复杂的多账号通知配对逻辑
  • 过细的展示区域组合开关
  • 为不同运行环境分支出来的大量启动逻辑

这一层默认不迁移,除非后续证明有明确价值。

4. 功能取舍

4.1 必须保留

  • 配置加载的核心子集
  • 热榜抓取能力
  • RSS 抓取能力
  • 统一新闻 / RSS 数据模型
  • 关键词匹配、分组、过滤
  • 排名与热度统计
  • 调度器
  • 本地 SQLite 存储
  • 面向自动化的结构化结果输出

这些功能构成 TrendRadar 的最小产品闭环,没有它们就不是 TrendRadar。

4.2 首版应删除

  • 程序版本在线检查
  • 配置文件版本在线检查
  • 自动打开浏览器预览
  • doctor 体检的大量环境特判
  • 多平台、多账号通知的复杂限制逻辑
  • 展示区域顺序、开关、组合策略的细粒度配置
  • 各类“只为展示效果存在”的输出分支

这些能力要么不是核心价值,要么实现复杂度明显高于收益。

4.3 首版应延后

  • AI 分析
  • AI 翻译
  • MCP 写操作与管理操作
  • 远程对象存储
  • 全量通知渠道
  • 与 GitHub Actions 深度绑定的工作流细节

这些功能仍然有价值,但不应阻塞 Rust 内核成型。

4.4 需要重设计而不是照搬

  • 通知系统:从“内置大量渠道”改为“少量核心渠道 + 可扩展 sink”
  • 配置系统:从“大而散的全局配置”改为“分模块配置结构体”
  • 运行入口:从“超大 __main__ 编排器”改为“薄 CLI + pipeline”
  • 存储层:从“运行环境驱动选择后端”改为“明确声明本地存储,远程后端后续插件化”
  • MCP:从“和主程序复用 Python 逻辑”改为“直接调用 Rust 内核能力”

5. Rust 目标架构

建议 Rust 仓库按“内核优先”组织,而不是按旧 Python 目录照搬。

5.1 推荐模块

  • crates/domain 统一数据模型、枚举、错误类型、公共 trait
  • crates/config 配置加载、校验、默认值、兼容转换
  • crates/fetch 热榜 API 抓取、RSS 抓取、解析和重试
  • crates/analyze 关键词匹配、统计聚合、排序权重、结果汇总
  • crates/schedule timeline 解析、时间段命中、一次性执行判定
  • crates/storage SQLite schema、读写接口、查询接口
  • crates/report JSON 输出和精简 HTML 输出
  • crates/app pipeline 编排和 CLI 入口

5.2 架构边界

  • domain 不依赖其他业务 crate
  • analyzeschedule 尽量保持纯函数化
  • storage 只负责持久化,不夹带业务判定
  • app 只负责编排,不承载核心业务算法

这套边界的目的,是让核心逻辑可单测、可复用、可被未来 MCP 直接调用。

6. 迁移顺序

Phase 0:行为冻结

先在旧仓库补迁移基线,不写 Rust 业务代码。

产出:

  • 关键输入输出样本
  • 调度解析样本
  • 词频与排序样本
  • SQLite 数据样本
  • RSS 解析样本

验收标准:

  • 对核心链路有可重复运行的固定样本
  • 能用样本判断 Rust 实现是否偏离

Phase 1:定义 Rust 契约

先确定 Rust 的领域模型和配置子集,不急着写抓取逻辑。

产出:

  • NewsItem / RssItem / NewsBatch / ScheduleDecision 等核心类型
  • 配置文件最小子集定义
  • 错误模型

验收标准:

  • 所有后续模块都以这套契约为基础
  • 不再出现“每层自己定义一套字段结构”

Phase 2:落地纯逻辑模块

优先实现:

  • schedule
  • analyze
  • 基础 domain

原因:

  • 风险最低
  • 可测试性最好
  • 最容易和 Python 行为做一一比对

Phase 3:落地抓取与存储

实现:

  • 热榜抓取
  • RSS 抓取
  • SQLite 存储
  • 基础查询

这一阶段完成后,Rust 已经具备独立运行的数据闭环。

Phase 4:落地最小交付能力

实现:

  • CLI 命令
  • JSON 输出
  • 精简 HTML 报告
  • 1 到 2 个核心通知渠道

建议只保留最常用通知渠道,其他渠道后续再做。

Phase 5:再评估 AI / MCP

当 Rust 内核稳定后,再判断:

  • MCP 是否直接基于 Rust 实现
  • AI 分析是否保留在独立服务层
  • 是否需要 Python 兼容层

不要在前四个阶段之前引入这些复杂点。

7. 首版建议产品边界

Rust 首版建议控制在以下范围:

  • 支持热榜抓取
  • 支持 RSS 抓取
  • 支持关键词过滤与聚合
  • 支持调度
  • 支持本地 SQLite
  • 支持 JSON 输出
  • 支持精简 HTML 报告
  • 支持少量核心通知渠道

Rust 首版明确不做:

  • AI 分析
  • AI 翻译
  • 远程对象存储
  • 全量通知矩阵
  • 全量 MCP 工具
  • 所有旧配置兼容

这会让首版更像一个稳定的“数据雷达内核”,而不是把旧系统重新背一遍。

8. 判断是否保留某功能的标准

迁移中每个功能都用同一套问题筛选:

  1. 没有它,核心链路还能不能成立?
  2. 用户是否高频直接感知它的价值?
  3. Rust 重做它,是否能明显提升稳定性、性能或可维护性?
  4. 它是否只是为了兼容旧实现、旧部署或旧展示?
  5. 它是否会显著拖慢首版交付?

若一个功能同时满足以下条件,应删除或延后:

  • 不影响核心链路
  • 用户感知弱
  • 维护成本高
  • 主要是历史兼容产物

9. 首批实施建议

Rust 仓库第一批落地工作建议是:

  1. 建 workspace 和基础 crate 结构
  2. 定义领域模型与错误类型
  3. 导入最小配置结构
  4. 先实现调度器
  5. 再实现关键词分析和排序
  6. 最后接抓取和 SQLite

不建议第一批就做通知、MCP、AI。

10. 结论

本次迁移应当以“缩小系统、澄清边界、沉淀内核”为目标,而不是“完整复刻旧系统”。

Rust 版本应该是:

  • 一个更小的系统
  • 一个边界清楚的系统
  • 一个可以先跑核心价值、再按需扩展的系统

如果后续执行严格遵守“核心优先、冗余删除、集成延后”这三条线,迁移成本会显著低于全量重写,且更容易真正完成。