nyaKazuha
|
a729615a48
|
fix(sync): 移除多线程下载并补齐staging复用回归
|
2026-07-24 10:34:58 +08:00 |
|
 nyaKazuhaandClaude Fable 5
|
0ab3f3b953
|
feat(download): 多线程下载 + 重试指数退避(issue #17)
下载主循环由串行改为「并发下载 + 串行簿记」三段式:
- Phase A:无网络前置校验(官方性/目标路径/建目录)+ 判定跳过/需下载,
非官方 URL 在任何下载前 fail-fast
- Phase B:need-download 项经 scoped 线程池并发下载(默认并发 4,
可配 1..=256)。worker 只做只读 &self 的 pull_one(各 URL 独立
.part/目标文件),经 mpsc 把结果送回主线程;manifest/quarantine
簿记与进度回调全在主线程串行执行,无需加锁。首个失败或 should_cancel
置 cancel 标志,其余 worker 在任务边界停止
- Phase C:按 plan 顺序串行收尾——seed .hash 校验(顺序相关、可
fail-fast)+ 构建有序结果
fail-fast 与「不发布不完整资源」不变量保留;进度事件按 URL 配对但
顺序不再单调(并发下天然如此)。
curl 重试加指数退避(网络类 200ms→400ms→800ms…上限 5s;ETXTBSY 仍走
极短退避),并发下对官方 CDN 更礼貌;退避基值 cfg(test) 下为 0 不拖慢
单测。
并发度经 OfficialUpdateConfig.download_concurrency 贯通,CLI
--download-concurrency 与 BAT_DOWNLOAD_CONCURRENCY 可配,.env 模板
与 USERGUIDE/CURRENT_STATUS/CHANGELOG 同步。
验证:新增并发正确性测试(并发 8:每 URL 恰一次 started+finished、
全部落盘)、并发度钳制、退避时长计算、CLI/env 解析单测;progress
排序测试改为顺序无关不变量;workspace 全测试(20 套件) + fmt +
clippy --all-targets -D warnings 全绿。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-18 03:25:04 -07:00 |
|
 nyaKazuhaandClaude Opus 4.8
|
d4d6d0a686
|
fix(curl): 将 ETXTBSY 归为可重试的瞬时启动失败
启动 curl 子进程时命中的 ETXTBSY(可执行文件忙)是多线程程序里
fork/exec 与"刚写出的可执行文件"之间的瞬时竞态:另一线程 fork 出的
子进程在 fork 与 execve 之间短暂持有目标文件的可写句柄,导致本次
exec 被内核判为忙。此前它被并入 ProcessFailed 且 retryable=false,
per-URL 层直接放弃。
新增 CurlFailureKind::ProcessBusy(retryable=true),在 process_failed
中按 io::ErrorKind::ExecutableFileBusy 精确识别,并在 busy 重试前做
极短退避让兄弟进程完成 execve。生产中 curl 是固定系统二进制、从不
被并发改写,故此变更对真实下载无影响,仅消除集成测试在高并发下偶发的
"Text file busy" flake(fetch_bootstrap unwrap 失败)。
验证:以 8-10 并发 worker × 8 线程 / 4 核(≈64-80 线程超载)复现,
修复前首轮即挂;修复后 200+ 次超压运行零 ETXTBSY、零失败。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-17 07:30:20 -07:00 |
|
 nyaKazuhaandClaude Fable 5
|
ab11cc899d
|
feat(official-sync): 下载失败携带类型化错误码
用类型化错误(不做 message 匹配)把资源下载失败归到准确的 BAT-ERR 码:
- curl_transfer:CurlFailureKind::error_code() 映射到网络域码(403→300001、
404→300002、5xx→300005、dns/connect/timeout/tls/interrupted→30001x、
proxy→310001、其余→300015);CurlRetryError::final_error_code() 取末次失败的码。
- official_download:新增 pub DownloadError { code, message },From<String>→internal,
Display/Error;pull_* 的返回类型由 String 改为 DownloadError,内部 String 错误经
From 归 internal,下载失败边界带 pull_one 的 error_code(),非官方 URL 带
non_official_url(300030)。
- official_update:pull 错误改用 anyhow::Error::new 保留 DownloadError 类型。
- 任务 worker:downcast DownloadError 取 code 写入任务记录的 error(失败不再一律
900001),非下载失败仍归 internal。
验证:新增 kind→code 映射单测;pull 404 测试断言 DownloadError.code()==HTTP_NOT_FOUND;
lib/core 全量测试通过,clippy --all-targets 干净。
范围说明:本次覆盖资源下载路径;launcher/metadata 拉取(official_launcher)的网络
失败仍归 internal,可按同一模式后续接入。
对应 issue #1(错误码细分映射,第一批)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-17 07:01:31 -07:00 |
|
 nyaKazuhaandClaude Fable 5
|
0656ad05c7
|
refactor(official-sync): CLI 工程卫生清理
- doctor daemon_status 检查(3-3):ok 与 message 原分别取自解析结果和文件存在性,
文件存在但解析失败时会“ok=false 却提示可解析”。改为从同一次解析结果派生两者。
- localize_error_message(3-1a):空壳直通占位函数,删除并在 4 处调用点直接用消息。
- daemon 路径 helper 形参(3-1b):output_root 实际语义是 state_dir,统一改名消除误导。
- stop_daemon 非 RPC 路径(3-1c):删除无意义的 let-else(_pid 读后丢弃、两分支
逐字重复 stop_daemon_inner+print_report),stop_daemon_inner 内已做 PID 校验。
- parse_http_status(3-1d):改为锚定 curl stderr 中 "error" 之后再取三位状态码,
避免误取端口/字节数等无关三位数字;新增锚定测试。
- 非 Unix process_exists(3-1e):补注释说明保守返回 true 的理由(无法探测存活,
避免误回收可能仍在运行的 daemon)。
对应 issue #18 维护清单 3-1、3-3。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-16 09:35:31 -07:00 |
|
 nyaKazuhaandClaude Fable 5
|
b570f37359
|
fix(official-sync): 区分代理故障并前置校验代理配置
- 代理故障分类:curl 因代理 407 认证失败(CONNECT 隧道失败)、无法解析/连接
代理等,原被归为普通可重试网络错误,永不成功也会耗尽 per-URL 重试且无诊断。
新增 CurlFailureKind::Proxy,从 curl stderr 识别代理故障,per-URL 层 fail-fast
不重试(daemon error-retry 循环仍整体重试以覆盖代理短暂抖动),并在失败摘要里
以 kind=proxy 明确标注。
- 前置校验:parse_proxy_config 新增 validate_proxy_url,拒绝拼错的代理 scheme
(如 htp://),只接受 http/https/socks4/socks4a/socks5/socks5h 或无 scheme
的 host:port。
- doctor:proxy 检查不再恒 ok,对解析出的代理 URL(含 auto 从环境变量取得的)
做 scheme 校验,前置暴露配置错误。
新增单测:代理 407/解析失败归为 Proxy 且不重试、源站连接失败仍为 Connect 可重试、
拒绝不支持的 scheme、无 scheme host:port 接受。
对应 issue #18 维护清单 2-5。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-16 08:18:37 -07:00 |
|
 nyaKazuhaandClaude Fable 5
|
565fd317de
|
fix(official-sync): curl 代理改由环境变量传入,堵住 argv 泄漏
apply_curl_proxy 原来对 URL 型代理执行 command.arg("--proxy").arg(url),
把可能含凭据的代理 URL 放进 curl 子进程 argv,会出现在 curl 进程的
/proc/<pid>/cmdline(0444,世界可读,每次下载存活期间可被本地任意用户读到)。
改为先 remove_proxy_env 清除所有继承的代理变量,再通过 ALL_PROXY/all_proxy
环境变量把代理传给 curl(大小写两种写法都设,避免 curl 只读其一)。凭据从
世界可读的 cmdline 转移到仅属主可读的 /proc/<pid>/environ(0400)。no_proxy
列表不含凭据,仍以 --noproxy 参数传入;disabled 模式保持 --noproxy * 直连。
至此代理凭据泄漏面全部堵住:daemon 子进程 argv、0600 状态文件(55b9bab),
以及本次的 curl 孙进程 argv。
验证:
- 新增单测用 Command::get_args/get_envs 断言 URL 只进 ALL_PROXY 环境变量、
不进 argv,且 scheme 专用变量被清除;disabled 模式强制直连。
- 真机经本地混合代理 127.0.0.1:7897 端到端验证:curl shim 记录 11 次调用,
凭据 0 次进 argv、0 个 --proxy 参数,代理仅在 ALL_PROXY 环境变量中;curl
确实经该代理到达官方 launcher/CDN/resources.assets 端点,功能未回归。
- 对抗性审查确认 auto/disabled/no_proxy 语义与旧 --proxy 等价,env 先删后设
最终为 set,无其它遗漏的凭据落 argv/日志/状态文件路径。
对应 issue #18 维护清单 1-2 残留项(curl 子进程)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-16 06:44:03 -07:00 |
|
 nyaKazuhaandClaude Fable 5
|
eef8c52497
|
fix(official-sync): 脱敏代理凭据避免泄漏到日志与状态输出
两处代理凭据泄漏:
- redact_proxy_url 对无 scheme 的代理串(user:secret@host:port,curl 默认按
http 处理)完全不脱敏,明文凭据会进入 progress 事件、daemon 日志和
bat-events.jsonl。现对无 scheme 但含 userinfo 的情况一并脱敏。
- daemon 保存的 command 含原始代理 URL,经 RPC status 和 bat status --json
回显到 stdout(会被监控采集)。新增 redact_command_proxy_credentials,在
build_daemon_status_report 的对外拷贝里脱敏 --proxy 值;磁盘状态文件
(0600)仍保留原始 command 供 restart/reload 复用。
残留:子进程 argv 仍可经 /proc/<pid>/cmdline 读到代理凭据,以及 0600 状态
文件内的 at-rest 凭据,二者受进程属主与文件权限约束,后续可改由环境变量下
传子进程进一步收敛。
对应 issue #18 维护清单 1-2。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-16 04:31:10 -07:00 |
|
nyaKazuha
|
c123f6c0dc
|
feat(official-sync): 支持本地代理下载官方资源
|
2026-07-16 00:12:27 +08:00 |
|
nyaKazuha
|
4192d7ee4c
|
fix: classify official download failures
Distinguish terminal HTTP errors from retryable CDN/network failures, record quarantined resources, and report failed download progress.
Fixes #7
|
2026-07-14 01:30:12 +08:00 |
|