Skip to content

K2GO-443 feat(code-assets): build-assets updater on the durable job engine - #626

Merged
luisguzman-adfa merged 10 commits into
mainfrom
feat/K2GO-443-updater-progress
Oct 3, 2026
Merged

luisguzman-adfa merged 10 commits into
mainfrom
feat/K2GO-443-updater-progress

Conversation

@luisguzman-adfa

Copy link
Copy Markdown
Collaborator

Build-assets content updater moves from the fire-and-forget refresh wrapper to
the durable job engine (aria2c): live progress (percent/speed), pause/resume/
retry, and resilience to a network change or drop. Incremental: unchanged files
reuse by their published .md5, only changed files download; the staged tree
swaps in atomically and restores on a failed swap.

dash-node 1.3.11: code-assets is a job type (POST /code-assets/download,
GET /code-assets/jobs/:id, pause/resume/retry/cancel over the generic /:type/*
surface). Runner sockets/code_assets.exec.ts + shared sockets/aria2-download.ts;
the mirror keeps the content work (--print-aria2-input / --finalize-only).

App: CodeAssetsDownloadService (foreground) + reworked CodeAssetsRefresh
(determinate bar, speed, pause/resume/cancel).

Carries K2GO-449 slice 1 (the shared base this needed): ContentDownloadServiceBase
and the ModuleActions registry; build-assets adopts them, add-ons and forgejo
migrate in later PRs.

Verified: device-tested end to end on the OnePlus. A deleted served asset is
re-downloaded into its correct release/ subdir, finalized, atomically swapped,
and served as application/octet-stream.

ADRs: ADR-updater-progress-resilience.md, ADR-content-module-extraction.md.

…ce via the aria2 job engine

Content updaters (add-ons, build assets) adopt the durable job engine + aria2c
(percent/speed/pause/resume/retry, Wi-Fi-drop resilience), reusing the kiwix/maps
runner template; the mirror keeps verify + page + swap. Forgejo reports per-repo
git progress. Dashboard rebuild (K2GO-383) gains percent + ETA + persist on the
compile. One progress contract + one shared app component; rides the content-module
shared extraction. Covers K2GO-443 and K2GO-383.
…b runners

Extract the canonical aria2 flag set + the withRetry outer loop (survives a full
interface loss, resumes via --continue) + rate parsing into one downloadWithAria2
primitive, so new runners (code_assets next) do not copy the flags a fourth time.
kiwix.exec.ts / maps-base.exec.ts keep their copies until migrated here. Typechecks.
…ne (dash-node 1.3.11)

Add a 'code-assets' durable job type: POST /code-assets/download + the generic
/:type/* status/pause/resume/retry/cancel, like kiwix/maps. The runner downloads
the build assets with aria2c (resilient: --continue resume, survives a Wi-Fi drop)
via the shared downloadWithAria2 helper; the mirror verifies each file by its
published .md5 and writes the page (mirror_code_assets.py --finalize-only, md5
streamed); the runner swaps the staged tree atomically. Pause keeps the partial
(resume via --continue), cancel discards it. The older /code-assets/refresh stays
for now. tsc clean; python py_compile + --print-aria2-input verified.
…ncy guard + swap restore

Review of slice 1:
- Incremental (was re-downloading all ~0.8 GB every time): --print-aria2-input now takes
  --reuse-from, stages unchanged files from the live tree and emits an aria2 input for only the
  changed ones; empty input -> the runner reports 'up to date' and keeps the live tree.
- Integrity via aria2: each emitted entry carries checksum=md5=<published>, so aria2 verifies
  during the transfer; --finalize-only just builds the page (no re-fetch, no re-hash of 0.8 GB).
- Concurrency: code-assets stages into one shared tree, so POST /code-assets/download returns 409
  when a build-assets job is already active (the app re-attaches; this is the hard guard).
- Swap: restore the previous tree if the final rename fails, so a failed swap never leaves the box
  with no served assets.
Plan output verified (checksum lines + staged sidecars); tsc clean; py_compile OK.
… pause/resume)

The 'Update build assets' action now drives the durable job engine instead of the
log-tail wrapper: a new foreground service CodeAssetsDownloadService (a single-item
ContentDownloadSession, type code-assets, modeled on ZimDownloadService) runs the
download so a ~0.8 GB transfer survives the view going away, and CodeAssetsRefresh
shows a determinate bar + speed with Pause/Resume and Cancel, re-attaching to a
running session. Removes the now-unused CodeAssetsRefreshClient (log-tail). The
box-side /code-assets/refresh route stays for older APKs. No new strings (reuses
k2go_dl_pause/resume + existing outcome strings). compileStandardDebug clean.
…iew detach (review)

- Check hasFailed() before isComplete(): isComplete() is true for an all-FAILED
  session, so a failed update was reporting the success message.
- Clear the session listener on the view's onViewDetachedFromWindow, not only on
  the next render, so a paused download after the sheet is dismissed cannot keep a
  destroyed Activity alive.
- Wire the listener directly (publish() already posts to main); drop the extra hop.
compileStandardDebug clean.
…ets service adopts it

First slice of the content-module extraction. ContentDownloadServiceBase holds the
generic foreground-service shell (onStartCommand pause/resume/cancel/retry dispatch,
notification + channel, ContentDownloadSession.Host), with per-module hooks (session,
action strings, notification text, START item). CodeAssetsDownloadService now extends
it and keeps only its module bits + the static UI API. ZimDownloadService /
BooksDownloadService / maps migrate onto the base in later, separately reviewed slices
(not touched here). ADR: controller/docs/ADR-content-module-extraction.md.
compileStandardDebug clean.
…e-action ifs

ModuleActionSheet and ModuleDetailFragment no longer carry a per-module if for the
installed update action (code_addons, code_assets): both read the action from a
ModuleActions registry (label + icon + handler, keyed by module key). A new content
module registers one entry instead of editing two shared UI files. Behavior-preserving;
Forgejo's repos action stays special (status-gated). Static registry, no runtime state.
compileStandardDebug clean.
…e subdirs

aria2 did not honor an out= that contains a subdir: it wrote to the -d root.
That also collided the v7/v8 same-named android-sdk/bootstrap files. Emit an
absolute per-entry dir= plus a basename out= so each file keeps its subdir.
@luisguzman-adfa
luisguzman-adfa merged commit dbdcf8d into main Oct 3, 2026
4 checks passed
@luisguzman-adfa
luisguzman-adfa deleted the feat/K2GO-443-updater-progress branch October 3, 2026 15:06
@luisguzman-adfa
luisguzman-adfa restored the feat/K2GO-443-updater-progress branch October 3, 2026 16:25
@luisguzman-adfa
luisguzman-adfa deleted the feat/K2GO-443-updater-progress branch October 3, 2026 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant