5.0 KiB
5.0 KiB
df-relay + df-tunnel + df-project + df-types + df-execute 代码走查报告
走查日期: 2026-08-02 范围: df-relay(5 文件, 30KB) + df-tunnel(3 文件, 32KB) + df-project(2 文件, 21KB) + df-types(3 文件, 42KB) + df-execute(2 文件, 34KB)
一、df-relay 云中继
问题汇总
| # | 等级 | 文件 | 类型 | 简述 |
|---|---|---|---|---|
| 1 | 🟡 P1 | relay.rs | risk | token 鉴权用 env DF_RELAY_TOKEN 全局常量,生产级应有独立 token 每 device |
| 2 | 🟡 P1 | relay.rs | risk | 注册表 tokio::sync::Mutex 锁粒度粗,高并发连接时瓶颈 |
| 3 | 🟢 P2 | conn.rs | smell | ConnRegistry::route 中 BroadcastMessage 字段 kind/from/handle.kind 三因子匹配,可读性差 |
| 4 | 🟢 P2 | broadcast.rs | smell | ControlMessage 定义了但 handle_inbound_text 中只处理 ping,其余控制消息未实现 |
正面评价
- 架构清晰: Event/Command/Control 三方向路由,语义明确
- Hello 握手: 双因子校验(kind + token),超时 10s,error 帧回显
- 心跳处理: 小程序 ping → relay pong 本地响应,不经过 device
- BroadcastMessage 全字段: device_id/kind/source/from/payload/ts,路由信息完整
二、df-tunnel 隧道客户端
问题汇总
| # | 等级 | 文件 | 类型 | 简述 |
|---|---|---|---|---|
| 1 | 🟡 P1 | tunnel.rs | risk | 重连退避逻辑写了 backoff_delay 函数但未实现自动后台重连,需手动 connect |
| 2 | 🟡 P1 | tunnel.rs | risk | cleanup_conn 中 select! 500ms 超时后 abort task,可能丢最后一帧 |
| 3 | 🟢 P2 | tunnel.rs | smell | WsTunnelClient 持 3 个 Mutex<Option<String>>(server_url/device_id/token),可合并为单 struct |
| 4 | 🟢 P2 | tunnel.rs | smell | connect 方法 130 行,逻辑过重,可拆为 do_connect + handshake + start_loop |
正面评价
- 协议对齐: 与 df-relay 的 Hello 握手协议一致
- connect_timeout: 15s 超时防 TCP SYN 无响应时永久挂
- HANDSHAKE_PROBE: 3s 窗口探测 relay 是否拒绝,防静默失败
- 心跳间隔: 25s 应用层 Ping,防 NAT 连接表超时回收
- CommandHandler:
BoxFuture回调,不阻塞收发循环 - send_raw_event: AiChatEvent 全 19 变体透传,不依赖强类型
三、df-project 项目管理
问题汇总
| # | 等级 | 文件 | 类型 | 简述 |
|---|---|---|---|---|
| 1 | 🟢 P2 | manager.rs | smell | ProjectManager::create 纯领域层工厂,但 Project 实体与 ProjectRecord 模型不同源 |
| 2 | 🟢 P2 | scan_helpers.rs | smell | 图片收集 is_badge_image 依赖域名+关键词列表,is_pure_badge_line 行级扫描逻辑复杂 |
正面评价
- 状态机完整:
can_transition矩阵清晰,transition返回TerminalState/IllegalTransition区分 - scan_helpers 纯函数: 无 IO 依赖,
strip_readme_noise处理 frontmatter/HTML注释/TOC/徽章 - 否定前缀处理: 单字(不/无/非/未/没/勿)+两字(没有/并非/毫无等)否定前缀,设计精细
- 测试覆盖: manager.rs 7 个测试,scan_helpers.rs 10 个测试
四、df-types 类型定义
问题汇总
| # | 等级 | 文件 | 类型 | 简述 |
|---|---|---|---|---|
| 1 | 🟢 P2 | augmentation.rs | smell | 21KB 单文件,MentionRef/Augmentation/ResolveError 三个模块混在一起 |
| 2 | 🟢 P2 | types.rs | smell | ExecutionId/ToolCallType newtype 大量 From/PartialEq 样板,可取 derive_more |
正面评价
- SanitizedPath newtype: 脱敏路径强制类型化,防裸 String 误用
- MentionRef/Augmentation 双结构: resolve 前/后分离,职责清晰
- serde tag=kind: 四种变体统一 json 结构,前端可共用 chip 渲染
- TaskStatus 双源一致性:
as_str()const fn +valid_values()测试锁定 - WorkflowEvent 兼容:
#[serde(default)]向后兼容老事件
五、df-execute 命令执行
问题汇总
| # | 等级 | 文件 | 类型 | 简述 |
|---|---|---|---|---|
| 1 | 🟡 P1 | shell.rs | risk | build_command 中 ShellType::default() 依赖 PWSH_CACHE 异步填充,首次 execute 可能读到未初始化 |
| 2 | 🟡 P1 | env_snapshot.rs | risk | probe_version 内 std::process::Command::output() 无 timeout,Windows Store alias 卡死(已修复 5s timeout) |
| 3 | 🟢 P2 | shell.rs | smell | execute_streaming 的 on_output 回调在 select! 中调用,FnMut 不可重入 |
正面评价
- PWSH_CACHE 单源: 异步 probe + 同步读取,死缓存已修复
- execute_streaming: mpsc 通道解耦 + 逐行回调 + read_to_end 兜底
- kill_on_drop: 超时后子进程不残留
- CREATE_NO_WINDOW: Windows 后台静默执行不弹黑窗
- env_snapshot 超时兜底: 5s timeout + spawn_blocking 防永久卡
- extract_version_token: 鲁棒版本号提取,"2.41.0.windows.1" → "2.41.0"
- 测试覆盖: shell.rs 探测缓存测试,env_snapshot 7 个测试