Skip to content

fix(desktop): stop hoarding installed runtime archives - #357

Merged
thcp merged 1 commit into
mainfrom
fix/prune-stale-appdata
Aug 12, 2026
Merged

fix(desktop): stop hoarding installed runtime archives#357
thcp merged 1 commit into
mainfrom
fix/prune-stale-appdata

Conversation

@thcp

@thcp thcp commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Every runtime pack a user ever installed stayed on disk at full size.

Closes #356

What was wrong

extract_runtime_pack deletes its temp directory and the runtime it displaced, but never the archive it extracted from. Measured on a machine running 0.8.0-alpha.13:

165 MB  StemDeck-runtime-macOS-arm64.tar.zst   18 Jul
 26 MB  ffmpeg-macos.zip                        4 Jun
 26 MB  ffprobe-macos.zip                       4 Jun

207 MB of a 1.3 GB app-data directory, none of it reachable again.

What changed

The archive is removed once its runtime is installed. A version change additionally sweeps whatever the previous build left in downloads/, plus a runtime.tmp or runtime.old from a swap that did not finish -- that one can be a second full runtime, around 900 MB.

The expected archive is spared only while it is still needed. Its filename carries no version, so once the matching runtime is installed the pack is dead weight that would otherwise sit there looking current forever. runtime_is_current answers that question from the install manifest. Keeping it while an install is pending also means an update that already downloaded the pack does not fetch it twice, and a partial download is not deleted from under the request writing it.

Installing a stale pack was never a risk, incidentally: the manifest SHA256 is verified before extraction.

What is deliberately not swept

settings.json lives in this directory and now holds jobs_dir, the stems location from #354. Removing it would send a user who moved their library to an external disk back to the default folder, opening to an empty app with their stems stranded at the old path. There is a test that asserts it survives, alongside config.json, runtime/, ffmpeg/ and models/.

Those last three stay for a plainer reason: re-downloading ~350 MB on every update to produce an identical folder costs more than the disk it frees. The runtime already refreshes itself properly when its version changes, on all three platforms.

Testing

28 Rust tests, 9 new, covering: a stale archive removed while the expected one survives; nothing outside downloads/ touched; an unfinished swap cleaned while the live runtime stays; a missing folder tolerated; and the three states of runtime_is_current (matching, older, half-installed).

Best-effort throughout -- a file that will not delete is worth a log line, never a failed launch. cargo clippy -- -D warnings shows no findings this branch did not inherit from main, and cargo fmt --check is clean.

Not verified

The sweep paths were exercised through unit tests against temp directories, not a real update on a packaged build. The logic is small and the destructive parts are covered, but nobody has watched an actual version change free the space.

Closes #356

Every runtime pack a user ever installed stayed on disk at full size. The
extractor deletes its temp directory and the runtime it displaced, but
never the archive it extracted from. Found 207 MB on one machine: a 165 MB
pack from July plus two ffmpeg zips from June.

The archive is now removed once its runtime is installed, and a version
change sweeps whatever the previous build left in downloads/, along with a
runtime.tmp or runtime.old from a swap that did not finish -- that one can
be a second full runtime, around 900 MB.

The expected archive is spared only while it is still needed. Its filename
carries no version, so once the matching runtime is installed the pack is
dead weight that would otherwise sit there looking current forever. Keeping
it while an install is pending also means an update that already downloaded
it does not fetch it twice, and a partial download is not deleted from
under the request writing it. Installing a stale pack was never a risk: the
manifest SHA256 is verified before extraction.

Deliberately narrow, and the tests say so. settings.json in this directory
now holds the stems location (#354): removing it would send a user who
moved their library to another disk back to the default folder, opening to
an empty app with their stems stranded. runtime/, ffmpeg/ and models/ stay
too -- re-downloading 350 MB on every update to produce an identical folder
costs more than the disk it frees.

Best-effort throughout. A file that will not delete is worth a log line,
never a failed launch.
@thcp
thcp marked this pull request as ready for review August 12, 2026 12:53
@thcp
thcp merged commit 2f123ee into main Aug 12, 2026
8 checks passed
@thcp
thcp deleted the fix/prune-stale-appdata branch August 13, 2026 12:56
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.

[Bug]: The app data directory accumulates stale files across updates

1 participant