Repository navigation
feat(update): dashboard 展示二进制下载进度并挂接进行中的更新 - #1825
Conversation
独立二进制更新从 GitHub Releases 下载约 174MB 资产,同步 POST 期间前端 只能干等,重复点击撞上 409 update_in_flight 时直接渲染更新失败。 - binary-self-update 新增 onProgress:下载流上统计字节数(Content-Length 可得时给出总量),并在 checksum/probe/swap 阶段继续回报进行中状态 - /api/update/status 暴露本进程 updateInFlight 与 binaryUpdate 实时进度 - 顶部胶囊与设置页在 POST 等待期间轮询 status,真实百分比映射进安装段 进度环,checksum/probe/swap 阶段保持进行中显示 - POST 收到 409 update_in_flight 时不再报失败:按 status 挂接另一个标签页 或 CLI/定时任务中的更新,有字节显示字节,无字节显示等待;完成仅依据 版本状态判定(跨进程持锁不翻转 dashboard 内存标志),10 分钟超时提示 手动确认 Co-Authored-By: Claude Code <noreply@anthropic.com>
review 两项 P2: 1. 持续 503、网络异常或请求挂起时,超时判断位于 status 成功回调内, 10 分钟超时永远无法触发,顶部即使进入超时分支也不会停轮询。 pollUpdateStatus 的 timeoutMs/onTimeout 改由独立定时器驱动,触发时 先自动停止轮询再回调;两处观察入口(顶部胶囊、设置页)接入。 2. 观察到版本状态完成(behind=false/current 变化)只代表磁盘上安装 完成,dashboard 实例并未变化:胜方可能仍停在设置页重启确认上,CLI 更新则根本不重启。顶部胶囊不再直接 reload,改转 restarting 阶段, 复用 /__selfcheck 实例变化判据(90s 无变化提示手动刷新);设置页 观察完成只刷新状态并提示重启后生效,不打断既有重启确认。完成判据 抽为 observedInstallCompleted 纯函数,两处复用。 新增 8 个测试:超时在持续失败/持续 503 下仍触发且自动停止、stop 后 不触发;observedInstallCompleted 更新/回退各场景。共 108 项 Vitest 与 bun test 通过。 Co-Authored-By: Claude Code <noreply@anthropic.com>
|
感谢这个 PR!下面是自动评审的初步意见,最终以维护者审阅为准。 总体结论改动质量很好,没有阻断性问题:下载计数管线、四阶段(download/checksum/probe/swap)事件顺序、409 一个非阻断的测试强度建议
bytesReceived += chunk.length; // 若误写成 = ,单 chunk 流结果相同建议补一条多 chunk 用例,把「逐 chunk 累加」和「pipeline 开始前先发一帧 0」一起钉住(复用现有 it('accumulates bytesReceived across multiple chunks', async () => {
const dir = tmp();
const target = join(dir, 'botmux');
writeFileSync(target, 'OLD BINARY', { mode: 0o755 });
const chunkA = fakeAsset(0x41, 600_000);
const chunkB = fakeAsset(0x42, 1_200_000);
const events: BinaryUpdateProgress[] = [];
const stream = Object.assign(Readable.from([chunkA, chunkB]), {
headers: { 'content-length': String(chunkA.length + chunkB.length) },
});
await replaceStandaloneBinary('3.99.0', target, {
fetchStream: async () => stream,
fetchChecksum: async () => null,
probeBinary: probeOk,
onProgress: event => events.push({ ...event }),
});
const received = events.filter(e => e.phase === 'download').map(e => e.bytesReceived);
// First frame is the pre-pipeline 0; then one per chunk, cumulative.
expect(received).toEqual([0, 600_000, 1_800_000]);
});该用例在当前实现下通过;若计数误写成 另一个可选小项
CI 说明本分支基底较旧,CI 里唯一的红腿 再次感谢,进度环与挂接观察的体验改进很实用。 |
|
🚀 Released in v3.43.0 |
背景
Web Dashboard 独立二进制更新(install.sh 形态)从 GitHub Releases 同步下载约 174MB 资产,POST /api/update/run 长时间阻塞:前端无进度反馈,用户重复点击撞上 409
update_in_flight后直接渲染「更新失败」。错误分类(锁前/锁异常误报 409)由并行 PR 修复,本 PR 只覆盖下载体验。
改动
BinarySelfUpdateDeps新增onProgress。下载 pipeline 中插入计数 Transform,按 Content-Length 报告字节总量与已接收字节(chunked/测试流无 Content-Length 时 bytesTotal=null);checksum/probe/swap 阶段持续回报,100% 下载后 UI 仍显示进行中。/api/update/status增加本进程updateInFlight与binaryUpdate(phase/version/bytesReceived/bytesTotal)。升级与回滚两条二进制下载路径都接入,finally 清理。update_in_flight不再报失败:挂接另一个标签页或 CLI/定时任务中的更新——有字节显示 received/total (percent%),仅本进程标志位为真显示「另一个更新进行中」,跨进程持锁(标志位不可见)显示外部等待文案。验证
与并行错误分类 PR 的交界
两个 PR 都在 /api/update/run 二进制分支改动,hunk 相邻(本 PR 改 onProgress 接线与 finally,对方改 catch 的 FileLockTimeoutError 判定),合并时可能有一处轻量冲突,后合者 rebase 即可。
🤖 Generated with Claude Code