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)
This commit is contained in:
1 parent
449ded2cb7
commit
875b792206
17 files changed
+512
-170
No files matched your search
+26
-6
@@ -72,8 +72,12 @@ pub enum Source {
|
||||
/// (不是 `@main`)、字节数与 `sha256` 一起钉,任何一项对不上就拒绝落盘(见
|
||||
/// `unlucky_core::download::font`)。
|
||||
///
|
||||
/// `urls` 是**候选**:首选挂了才试下一个(两个都是同一份字节的镜像,哈希只认一份——
|
||||
/// 镜像若给了别的内容,校验那关会当场拒掉,而不是把别的东西注册成字体)。
|
||||
/// `urls` 是**候选**:首选挂了才试下一个。两个候选**必须是不同的失败域**(Cloudflare 侧 +
|
||||
/// Fastly 侧,见 [`NOTO_SANS_SC`] 的实测表);同一家 CDN 的两个域名不算冗余。
|
||||
///
|
||||
/// 每次尝试与整条取回都有整体时限(`unlucky_core::download::font` 的 `ATTEMPT_DEADLINE` /
|
||||
/// `TOTAL_DEADLINE`):慢而不死的连接(IPv6 爬行实测 67 KB/s)会在时限处被打断、转下一个
|
||||
/// 候选,而不是让用户在设置页干等四分钟。超时归「网络」档,界面文案是「网络不通或太慢」。
|
||||
Pinned {
|
||||
/// URL 候选(按顺序尝试)。
|
||||
urls: &'static [&'static str],
|
||||
@@ -105,7 +109,7 @@ pub struct CjkFont {
|
||||
/// |---|---|
|
||||
/// | 上游 | `google/fonts` 仓库的 `ofl/notosanssc/NotoSansSC[wght].ttf` |
|
||||
/// | 版本 | commit `2894aab31764f10f29c421bdfd2340d3b382d384`(该文件的最后一次改动,2022-12-09) |
|
||||
/// | 字节数 | 17 772 300(≈17.0 MiB) |
|
||||
/// | 字节数 | 17 772 300(16.95 MiB) |
|
||||
/// | sha256 | `a3041811a78c361b1de50f953c805e0244951c21c5bd412f7232ef0d899af0da` |
|
||||
///
|
||||
/// 为什么钉 commit 而不是 `@main`:`@main` 会随上游改动漂移,哈希一漂就成了「每次中文环境都下
|
||||
@@ -119,11 +123,27 @@ pub const NOTO_SANS_SC: CjkFont = CjkFont {
|
||||
license: "OFL-1.1",
|
||||
weights: &[100, 200, 300, 400, 500, 600, 700, 800, 900],
|
||||
source: Source::Pinned {
|
||||
// 两个候选**必须是不同的失败域**(M168 复审 P2-1):`cdn.jsdelivr.net` 与
|
||||
// `fastly.jsdelivr.net` 都 CNAME 到 `jsdelivr.map.fastly.net`(同一批 Fastly 边缘),
|
||||
// 「一个坏了换另一个」等于没有冗余——上一版就是这样,被复审当场打掉。
|
||||
//
|
||||
// 实测(两份独立的国内网络取证,同一份 17 772 300 B 内容,sha256 都是 a3041811…):
|
||||
//
|
||||
// | 域名 | 解析 | 本机(本 worktree 开发机) | 复审机(无代理) |
|
||||
// |---|---|---|---|
|
||||
// | gcore.jsdelivr.net | Cloudflare 104.16.x | 13.3 s 完整 | 16.6 s 完整 |
|
||||
// | testingcf.jsdelivr.net | Cloudflare 104.16.x | 11.8 s 完整 | 14.8 s 完整 |
|
||||
// | cdn.jsdelivr.net | Fastly 151.101.x | 11.9 s 完整(另两次 5.7 s / 14.9 s)| 1.1 s,但**走 IPv6 时 3 次都掉到 ≈67 KB/s**(60 s 只到 4.0 MB)|
|
||||
// | fastly.jsdelivr.net | 同上(Fastly)| — | 20 s 只到 2.5 MB(比它「要备的那条」还慢)|
|
||||
//
|
||||
// 排序依据(不是「听说更稳」):**首选放 Cloudflare 那一侧**——Fastly 侧的 IPv6 边缘
|
||||
// 在复审环境里会掉进 60~77 KB/s 的慢路径(那条路上 17.7 MB 要 ≈4 分钟),而 Cloudflare
|
||||
// 侧两份取证都完整下完、且是独立的失败域。二选留 Fastly 侧:本机它反而最快(5.7~11.9 s),
|
||||
// 保留它是为了「Cloudflare 一侧整体不可用时还有另一家 CDN」。
|
||||
// 先后只影响速度,不影响正确性:sha256 只认一份,镜像给了别的内容会被当场拒。
|
||||
urls: &[
|
||||
// 首选:jsDelivr(国内多数线路可达;`@<commit>` 保证内容不变)
|
||||
"https://gcore.jsdelivr.net/gh/google/fonts@2894aab31764f10f29c421bdfd2340d3b382d384/ofl/notosanssc/NotoSansSC%5Bwght%5D.ttf",
|
||||
"https://cdn.jsdelivr.net/gh/google/fonts@2894aab31764f10f29c421bdfd2340d3b382d384/ofl/notosanssc/NotoSansSC%5Bwght%5D.ttf",
|
||||
// 备用:同一份内容的另一个 jsDelivr 边缘(首选被墙/被限速时才用)
|
||||
"https://fastly.jsdelivr.net/gh/google/fonts@2894aab31764f10f29c421bdfd2340d3b382d384/ofl/notosanssc/NotoSansSC%5Bwght%5D.ttf",
|
||||
],
|
||||
sha256: "a3041811a78c361b1de50f953c805e0244951c21c5bd412f7232ef0d899af0da",
|
||||
bytes: 17_772_300,
|
||||
|
||||
Reference in new issue
Block a user