harmonyos: resumable model download (pause/resume/cancel + cross-rest… - #36
Open
Leeson-Wong wants to merge 1 commit into
Open
harmonyos: resumable model download (pause/resume/cancel + cross-rest…#36Leeson-Wong wants to merge 1 commit into
Leeson-Wong wants to merge 1 commit into
Conversation
…art reattach) with cold-start paused-task fix
Collaborator
|
我在 目前有一个可稳定复现的阻断问题:
也就是说,同一模型会被重复创建下载任务,可能重复消耗数 GB 流量,并并发操作同一模型文件。原因看起来是 reattach 发布的 paused 状态又被后续文件扫描覆盖;在 tmp 尚未产生时,页面回到了 idle。 另外请一起检查:
这些下载生命周期问题修复并补充对应真机用例后,再考虑合入会更稳妥。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
HarmonyOS:可恢复的模型下载(暂停 / 继续 / 取消 + 跨重启 reattach)
简介 | Summary
为 HarmonyOS 客户端增加可恢复的、以文件系统为对账依据的模型下载子系统:支持暂停 / 继续 / 取消并保留
.tmp断点;App 重启后能 reattach 仍在存活的系统下载任务;多源竞速;UI 通过观察者模式与传输层彻底解耦。仅 HarmonyOS、仅 ArkTS。Adds a resumable, filesystem-authoritative model-download subsystem to the HarmonyOS client: pause / resume / cancel with partial-file preservation, cross-restart reattachment of surviving system download tasks, multi-source racing, and a UI fully decoupled from the transfer via an observer pattern. HarmonyOS only, ArkTS only — no native code touched.
关联 issue | Linked issues
背景 | Motivation
原来的 HarmonyOS 下载器没有暂停 / 取消,也无法跨 App 重启恢复:杀进程会留下写了一半的
.tmp,用户只能从头再来。模型文件动辄数 GB,在移动网络波动或误杀 App 时丢进度是主要痛点。The previous downloader had no pause/cancel and no recovery across app restarts: killing the app mid-download left a half-written
.tmpand the user had to start over. Model files are multi-GB; losing progress on a flaky connection or an accidental app kill was the main pain point.设计 | Design
设计方法论来自 DVA——领域建模(Domain Modeling)的个人实践总结,也可简单理解为领域建模。核心判据:变化速率对齐的归在一起,不对齐的拆开。 文件系统是唯一权威(扛任意 kill),UI 退成纯观察者。
The design methodology follows DVA — a personal synthesis of domain modeling; it can be read simply as domain modeling. Core criterion: group what changes together, separate what changes at different rates. The filesystem is the single source of truth (survives any kill); the UI is a pure observer.
时序图 | Sequence — 暂停 → 杀进程 → 重开 → 继续
静态结构见下方「实体 / 关系」表;本图展示动态行为——跨重启如何不腐败地恢复(本 PR 最关键、也最难一眼看懂的部分)。
Static structure is in the 实体 / 关系 tables below; this diagram shows the dynamic behavior — how a download recovers across a restart without corruption (the PR's most important, hardest-to-grasp part).
sequenceDiagram autonumber participant U as 用户 participant MM as ModelManager participant Svc as Service participant DM as DownloadManager participant T as request.agent.Task participant FS as .tmp(文件系统) U->>MM: 暂停 MM->>Svc: pause() Svc->>DM: pauseDownloadForFile DM->>T: task.pause() Svc-->>MM: 发 paused(保留 .tmp) Note over U,FS: ── 用户杀掉 App ── Note over FS: .tmp 留在盘上 = 对账依据 Note over U,FS: ── 重新拉起 App ── MM->>Svc: attach() Svc->>DM: reattachSystemTasks(search / show) DM->>T: getTask + 重挂 progress/completed/failed Svc->>FS: reconcileFromFs(statSync .tmp) Svc-->>MM: 发 paused(按 fs 字节,非 running) U->>MM: 继续 MM->>Svc: resume() Svc->>DM: resumeDownloadForFile DM->>T: task.resume() T->>FS: 续写字节 Svc-->>MM: running → completed实体 | Entities
.tmp文件loadedModelId关系 | Relationships(关键的"拆开"决策)
loadedModelId独立追踪实现 | What ships
.tmp。暂停保留断点,取消才丢弃。Pause / Resume / Cancel with
.tmppreservation. Pause keeps the partial file; Cancel discards it.request.agent.search找回存活的系统任务并重新挂回调,不会对同一.tmp起第二个任务导致冲突;杀进程前处于暂停的任务,重启后正确显示为「继续 / 取消」(而非「暂停 / 取消」)。On relaunch, surviving
request.agenttasks are discovered and re-attached, so no duplicate task ever writes the same.tmp. A task paused before the kill is surfaced as Resume/Cancel (not Pause/Cancel).fs.statSync(<file>.tmp),进度回调只是乐观覆盖。App 被任意时刻杀掉后,都能从盘上重推出一致状态。Bytes-on-disk always comes from
fs.statSync(<file>.tmp); progress callbacks are an optimistic overlay only. Coherent state is re-derived from disk after an arbitrary kill.ModelDownloadService把结构化DownloadSnapshot发到AppStorage,ModelManager/Index是纯观察者(@StorageLink+@Watch),与传输层完全解耦。ModelDownloadServicepublishes a structuredDownloadSnapshottoAppStorage; pages observe via@StorageLink+@Watch, fully decoupled from the transfer.request.agent的Config.begins追加到已有.tmp;续传前把竞速残留的.tmp合并成最大的那个。Range resume via
Config.begins; race-leftover.tmpconsolidated to the largest before resuming.已知局限 | Known limitation
以下行为已知,本 PR 未改动,根植于现有下载基础能力。
The following behaviors are known, not changed by this PR, and rooted in the existing download infrastructure.
实际影响:
The transfer runs in the OS download service; swipe/kill does not stop it. Use the in-app Cancel button.
No system download notification.
.tmp续上。Multi-file cold-start resume: only the in-flight file resumes via the surviving task; the queue is not auto-continued. Re-starting resumes from
.tmpvia Range.验证 | Verification
实测通过:
Uninitialized覆盖了 LLM 的ModelReady,误显示「未初始化」)。Verified on both devices above: status bar shows "Ready" correctly after re-entering Model Manager (previously showed "Uninitialized" due to a subscribe-time state clobber between LLM/TTS listeners); selecting a non-loaded model shows neutral status + "Load" (no stale "Ready") and no longer auto-loads; pause → kill → relaunch shows Resume/Cancel; rapid Pause is retryable with no dead-button state. Other HarmonyOS hardware classes not covered — happy if the team can verify on additional devices (Mate 60 / X series / tablets) where available.
改动文件 | Files
仅 HarmonyOS。无 iOS / Android / native 改动。
HarmonyOS only. No iOS / Android / native changes.
entry/src/main/ets/download/{DownloadState,ModelDownloadService,Reconciler}.etsentry/src/main/ets/utils/DownloadManager.etsentry/src/main/ets/pages/{ModelManager,Index}.etsentry/src/main/ets/engine/{LlamaEngine,TtsEngine,ModelInfo}.etsentry/src/main/resources/{base,en_US}/element/string.json