Implement resumable download queue (T-301)
This commit is contained in:
@@ -142,6 +142,17 @@ T-202 将本地识别拆为两层:
|
||||
|
||||
磁盘扫描结果必须在进入 Gio Layout 前准备好;UI 不直接读取 installed-app.json。完整字段见 [api.md](api.md),Schema 为 `schemas/installed-app.schema.json`。
|
||||
|
||||
T-301 下载队列:
|
||||
|
||||
- `core/downloader.Queue` 默认并发 2,用 request_id 主键和 app 非终态唯一约束串行化 enqueue/pause/resume/cancel/retry;网络/磁盘 IO 与事件发布都在全局锁外。
|
||||
- `.part` / `.download` / metadata 路径只由受限 request_id 派生。元数据通过 `core/storage.DownloadTaskStore` 临时文件 + backup 原子替换。
|
||||
- Range 必须绑定 strong ETag 或 Last-Modified 并发送 If-Range;无 validator 从 0 重下,`200` 忽略 Range 时创建新 attempt。进度只在 request_id+attempt 内单调。
|
||||
- pause/cancel/close 先取消 generation context,等待 body 关闭、part sync/close 和旧 worker 完全退出,再发布终态/释放并发槽,阻断迟到 progress。
|
||||
- cancel 一旦先于 completion 取得线性化点,即使 body close/sync 报错也记录后继续精确清理;若 completion 先完成,后续 cancel 明确拒绝。known-total 完整 part 在同进程 resume/retry 与启动恢复中都直接 finalize,不发送 offset==total 的 Range。
|
||||
- 写入句柄的文件身份贯穿 sync/close 与 rename 前后核对,防止活跃 `.part` 路径被替换后发布错误文件。崩溃恢复对账 metadata、part、final 三份事实:完整 part 可 finalize,已 rename 的 final 可补 completed metadata;缺 final 的 completed、part+final、超出 expected/unknown 上限均 fail closed。
|
||||
- 事件投递失败通过 `OnObserverError` 显式报告,不改变 durable transfer 结果;application/UI 启动或重连后用 `Queue.Tasks()` 对账终态,避免 DownloadCompleted 等一次性通知丢失后永久停链。
|
||||
- DownloadCompleted 仅证明传输字节完整落盘。下载元数据和 `.download` 可被本地篡改,T-302 不得把它们当信任根,仍需从已验签 Catalog 重新取得并核对身份/size/hash/signature。
|
||||
|
||||
### 4.3 事件模型
|
||||
|
||||
后台任务只发布事件(`DownloadStarted / DownloadProgress / DownloadPaused / DownloadCompleted / DownloadFailed` 等),UI 按 RequestID 和软件 ID 回填,见 [api.md](api.md) 事件合约。
|
||||
|
||||
Reference in New Issue
Block a user