AskaEth
|
875b792206
|
fix(m168): 复审 r1 五项 —— 修红的 integration target、独立失败域、整体时限
复审 r1(p1-1/fix-then-merge)五项全改:
1. **p1-1 CI 会红的 4 条 integration test**(`crates/core/tests/setting/`,我上一轮只跑了 `--lib`,
scope 漏掉了覆盖 schema 版本号的目录式 target):
- `java_install_keys` / `isolation_keys` / `appearance_keys`:版本断言 1.6.0 → 1.7.0(M168 的
`ui.font_cdn`),并写明「每加一批键推一次 minor 是纪律」。
- `update_keys::a_read_only_launcher_config_never_retires_the_legacy_file`:夹具从**写死
1.7.0** 改成 `launcher_version().minor + 1` 经 `SchemaRef::url()` 生成。写死数字的版本一推
这条守卫就变成「同版本」⇒ 文件可写 ⇒ 迁移真的执行 ⇒ 旧文件被退役,而断言还绿着(用户数据
守卫静默失效)。相对推导不会过期。
2. **p2-1 备用镜像不备用**:`cdn` 与 `fastly` 同属 Fastly(都 CNAME 到 jsdelivr.map.fastly.net),
换掉。现在首选 `gcore.jsdelivr.net`(Cloudflare,独立失败域),二选 `cdn.jsdelivr.net`
(Fastly)。注释里放了实测表(本机 + 复审机两份数据、字节数、sha256、IPv6 慢路径),
并写清排序依据(Fastly 侧 IPv6 实测 67 KB/s ⇒ 丢掉 4 分钟;Cloudflare 侧两次都完整下完)。
3. **p2-2 整体时限**:`core::download::font` 新增 `ATTEMPT_DEADLINE = 90 s` /
`TOTAL_DEADLINE = 180 s`,落在本模块自己的候选循环里(不动引擎全体语义):每次尝试
`min(单次上限, 剩余总预算)`,超时归 `Network` 档。新增守卫
`a_trickling_connection_is_cut_by_the_deadline`(回环服务端每 100 ms 挤 1 字节、预算 300 ms)。
顺带修掉一个真 bug:`tokio::time::timeout` 在运行时外构造会 panic(5 条既有用例当场抓到),
现在整段包进 `block_on(async { … })`。UI 文案改成「网络不通或太慢(超时)」,不校验失败混。
4. **p2-3 说 `Source::PendingPin` 的两处**:`fonts/cjk.rs` 的模块文档已改;`ui/lang.rs::log_cjk`
那句「D28 的下载通道还是 PendingPin」(在下载已发起之后打印,等于当面否定本功能)改成
「已按 D28 发起下载,见 [font] cjk-download … 与设置页那一行」。全仓再扫,只剩注释里的历史说明。
5. **p2-4 假守卫**:判据抽成纯函数 `install::plan(strategy, current) -> Step`(`Skip` / `Apply` /
`Start`),`after_probe` 只执行。旧的空转用例换成打真判据的打表用例;变异证明:删掉
`Skip` 那一臂 ⇒ `a_started_or_finished_install_is_not_restarted` 红(已实跑)。
次要项也一并处理:`from_cache` 改成**本次是否真的命中缓存**(`CdnFetcher::was_cached()`,
`has_cached()` 降级为诊断字段 `cache_present=`);`FontSpec` 的 URL 口径收紧为「非回环必须
https」(`is_acceptable_url` + 守卫);`ui.font_cdn` 写进状态行 hint;文档里的 17.0 MB → 16.9 MB。
`download/font.rs` 拆出 `font/spec.rs` 守 400 行。
验证(这台机器上单个 800 MB 测试 exe 链接要 10 分钟,链接期间文件被 Defender 扫描,故耗时很长):
- `cargo test -p unlucky-core --all-targets` → **1188 passed / 0 failed**(16 个 target,含
`setting` 那个 115 条、上一轮红 4 条的 integration target)
- `cargo test -p unlucky-i18n` → 31 passed / 0 failed
- `cargo test -p unlucky-app-iced --lib` → 685 passed / 0 failed
- `cargo clippy -p unlucky-i18n -p unlucky-core -p unlucky-app-iced --all-targets -- -D warnings` → 干净
- `cargo fmt --all -- --check` → 干净;全仓受检文件行数最大 388(<400)
|
2026-11-08 14:38:23 +08:00 |
|
AskaEth
|
449ded2cb7
|
feat(m168): 中文字体 CDN 下载真接线(D28 后半)
M167 调研的结论是「中文字体 CDN 下载至今未实装」:`i18n::font` 只有 `Fetcher` trait 与
假实现,`needs-download` 分支什么也不做。这条把它接成一条真链路。
判据 → 下载 → 注册(一条链,四个 crate 各管一段):
* `unlucky_i18n::font`(零依赖):`Source::Pinned { urls, sha256, bytes }` 把「下什么」
钉死——google/fonts 的 `NotoSansSC[wght].ttf` 钉到 commit `2894aab…`(不是 `@main`),
17 772 300 B / sha256 `a3041811…`。可变字体一份覆盖 wght 100–900,省掉三份静态子集的 25 MiB。
`FetchError` 补第三档 `Disk`(网络 / 校验 / 磁盘,UI 按类别选词)。
* `unlucky_core::download::font`(新):缓存命中 → 共享引擎 `download_bytes` → 复验(sha256 +
sfnt 魔数 + 32 MiB 上限)→ 原子落盘。**复验在写盘之前**,所以「哈希不符」时盘上什么都没有;
缓存按 `<sha256 前 16 位>` 命名,pin 一换自动换名。
* `unlucky_app_iced::fonts::{cdn,install}`(新):`CdnFetcher` 把 pin 接进 core(`ui.font_cdn`
可覆盖 URL,哈希不换);`install` 是状态机 + 后台线程,只有 `NeedsDownload` 才起线程
(英文 / 系统已有 / 探测不出一律零网络)。注册走 `iced_graphics::text::FontSystem::load_font`,
族名从字体库读回来核对。失败只降级(继续用系统字体),不阻塞、不崩。
* 接入两条路径:`fonts::resolve_with`(启动)与 `fonts::cjk_for`(设置页切语言)都调
`install::after_probe`;设置页 General 组多一行状态(下载中 / 完成 / 失败 / 无需下载 + 三类失败
原因),文案进 catalog 金表(链尾追加,既有顺序不动);`App::advance` 每秒比对状态快照后重建
视图模型,所以那一行会自己刷新。
配置:新增 `ui.font_cdn`(`keys/font.rs`,schema 1.7.0),空 = 内置 jsDelivr 镜像(含备用边缘)。
守卫(三条都能变红,变异证明见报告):core 侧 8 条(缓存不联网 / 哈希不符拒落盘 / HTML 不当字体
/ 坏缓存自愈 / 上限 / pin 校验),app 侧 6 条(三种闲置策略零调用、失败不注册、类别不串、幂等、
截图钉子、单行日志),页面侧 1 条(四态 × 两语言无缺译、不写假百分比)。
测试:`cargo test -p unlucky-i18n --lib` 31 绿;`-p unlucky-core --lib` 622 绿;
`-p unlucky-app-iced --lib` 684 绿;`cargo fmt --check` 干净。截图三张见报告。
|
2026-11-08 14:38:23 +08:00 |
|