背景
针对 ad-block DNS-mode 子系统(#130 + 后续 #132 /#133 /#134 /#138 /#154 /#180 )做了完整 review,发现一批遗留问题与可优化点。归档在此跟踪 issue 下,每个子项对应一个独立 issue,便于分工与回归。
涉及的核心文件:
src-tauri/crates/mhost-storage/src/adblock.rs
src-tauri/crates/mhost-dns/src/adblock.rs
src-tauri/crates/mhost-dns/src/matcher.rs
src-tauri/crates/mhost-dns/src/server.rs(handle_address_query 接入点)
src-tauri/src/commands/adblock.rs
src-tauri/src/commands/dns.rs(refresh task)
src-tauri/crates/mhost-core/src/models.rs(AdBlockState / AdBlockSource)
src/pages/AdBlock.tsx + src/stores/profiles/{state,actions}.ts
子 issue 索引
P1(✅ 已全部完成)
✅ #192 [bug] auto_refresh_enabled 是 dead field — 字段被持久化、被 spawn_ad_block_refresh_task 读取,但没有 IPC / UI 能设置它 ,用户实际无法关闭自动刷新。
✅ #193 [enhancement + perf] 实现 ETag 条件 GET 节省刷新带宽 — AdBlockSource.etag 已抓取并持久化,但从未发送 If-None-Match 。周期刷新每次都重新下载整份 blocklist,带宽与上游都被白白消耗。
P2(除 #196 外已完成/已关闭)
✅ #194 [tech-debt] 合并 fetch_and_cache_source 与 *_internal 两套几乎相同的逻辑 — 仅 storage 访问方式不同;风险是安全修复在某一分支漏掉(PR feat(adblock): add DNS-mode ad blocking #131 re-review P1-2 已踩过一次)。
✅ #195 [bug] 周期刷新 task 不响应 interval / auto-refresh 的运行时变更 — 用户改了"自动刷新频率"要等当前 tick 跑完才生效(最坏情况 168h)。
🔵 #196 [enhancement] 批量白名单操作 + 多行输入 UI — 现在 UI 一次只能加一条;批量粘贴 200 条要做 200 次点击 + 200 次 reload(清 LRU 缓存)。同时修正 remove 路径不同步走 validate_whitelist_domain 的隐患。
♻️ #197 [enhancement] 多源重叠规则的覆盖关系提示 + source 列表排序 — classify_rules 用 HashMap::entry().or_insert(),多源同名时"先到先得"且无文档/UI 提示。需要决策 NxDomain 优先 vs 当前顺序。
❌ #198 [perf] 缓存文件从 hosts 格式改为纯域名列表 — 当前每次刷新都要把 Vec<String> 序列化成 0.0.0.0 {d}\n、再让 Parser::parse 读回来;省掉这趟 round-trip + 加 ASCII lowercase 快路径。
P3(待做)
🔵 #199 [perf + enhancement] Ad-block 性能与可观测性 follow-up — 域名前缀 trie 替换 HashMap/HashSet、命中率/刷新耗时指标、禁用源 cache 清理等。
承接拆分(从 not-planned 的 #197 / #198 吸收实质诉求)
#197 / #198 关闭后,其核心诉求被拆解到独立 issue 继续追踪,避免 tracker 与现实脱节。
🔵 #215 [enhancement] Ad-block 多源重叠的 UI 可观测性 + source 排序 — 承接 [Enhancement] 多源重叠规则的覆盖关系提示 + source 列表排序 #197 的 UI 部分。后端前提失效(engine check() 本就确定性 NxDomain 优先),但 UI 可观测性诉求仍在。
🔵 #213 [feature] 支持纯域名格式的 blocklist 源(一行一个域名) — 承接 [Perf] ad-block cache 改为纯域名列表,跳过 hosts parser round-trip + ASCII lowercase 快路径 #198 的"格式统一"诉求。[Perf] ad-block cache 改为纯域名列表,跳过 hosts parser round-trip + ASCII lowercase 快路径 #198 的冷路径 cache 序列化优化收益有限 + 迁移有正确性风险不再做,但用户用纯域名 list 作为输入源的体验需要补齐。
不开 issue 的小项
状态更新(2026-09-15)
状态更新(2026-09-16)
背景
针对 ad-block DNS-mode 子系统(#130 + 后续 #132/#133/#134/#138/#154/#180)做了完整 review,发现一批遗留问题与可优化点。归档在此跟踪 issue 下,每个子项对应一个独立 issue,便于分工与回归。
涉及的核心文件:
src-tauri/crates/mhost-storage/src/adblock.rssrc-tauri/crates/mhost-dns/src/adblock.rssrc-tauri/crates/mhost-dns/src/matcher.rssrc-tauri/crates/mhost-dns/src/server.rs(handle_address_query 接入点)src-tauri/src/commands/adblock.rssrc-tauri/src/commands/dns.rs(refresh task)src-tauri/crates/mhost-core/src/models.rs(AdBlockState/AdBlockSource)src/pages/AdBlock.tsx+src/stores/profiles/{state,actions}.ts子 issue 索引
P1(✅ 已全部完成)
auto_refresh_enabled是 dead field — 字段被持久化、被spawn_ad_block_refresh_task读取,但没有 IPC / UI 能设置它,用户实际无法关闭自动刷新。AdBlockSource.etag已抓取并持久化,但从未发送If-None-Match。周期刷新每次都重新下载整份 blocklist,带宽与上游都被白白消耗。P2(除 #196 外已完成/已关闭)
fetch_and_cache_source与*_internal两套几乎相同的逻辑 — 仅 storage 访问方式不同;风险是安全修复在某一分支漏掉(PR feat(adblock): add DNS-mode ad blocking #131 re-review P1-2 已踩过一次)。remove路径不同步走validate_whitelist_domain的隐患。classify_rules用HashMap::entry().or_insert(),多源同名时"先到先得"且无文档/UI 提示。需要决策 NxDomain 优先 vs 当前顺序。Vec<String>序列化成0.0.0.0 {d}\n、再让Parser::parse读回来;省掉这趟 round-trip + 加 ASCII lowercase 快路径。P3(待做)
承接拆分(从 not-planned 的 #197 / #198 吸收实质诉求)
check()本就确定性 NxDomain 优先),但 UI 可观测性诉求仍在。不开 issue 的小项
validate_whitelist_domain(已在 [Enhancement] 白名单批量增删 + 多行输入 UI(同时修正 remove 校验) #196 中捎带修)useEffect重复 fetch、Tray 文案 i18n 等作为 PR review 时捎带处理状态更新(2026-09-15)
If-None-Match,304 语义有测试钉住)fetch_and_cache_source)check()本就确定性 NxDomain 优先、同类型重叠无行为差异;UI 可观测性部分拆至 [Enhancement] Ad-block 多源重叠的 UI 可观测性 + source 排序(承接 #197,后端已确定性无歧义) #215状态更新(2026-09-16)