fix(render): clear asset caches between watch renders - #242
Merged
Merged
Conversation
53 tasks
LeadcodeDev
force-pushed
the
fix/gif-decode-bomb
branch
from
September 22, 2026 06:10
c6adb3c to
7fa956d
Compare
LeadcodeDev
force-pushed
the
fix/watch-cache-invalidation
branch
from
September 22, 2026 06:10
408d3e4 to
a7a75fa
Compare
LeadcodeDev
force-pushed
the
fix/gif-decode-bomb
branch
from
September 22, 2026 08:34
7fa956d to
cb20470
Compare
LeadcodeDev
force-pushed
the
fix/watch-cache-invalidation
branch
from
September 22, 2026 08:34
a7a75fa to
581d1ad
Compare
LeadcodeDev
force-pushed
the
fix/gif-decode-bomb
branch
from
September 22, 2026 08:44
cb20470 to
4f6243e
Compare
LeadcodeDev
force-pushed
the
fix/watch-cache-invalidation
branch
from
September 22, 2026 08:44
581d1ad to
b02296e
Compare
LeadcodeDev
changed the base branch from
fix/gif-decode-bomb
to
chantier/audit-2026-09
September 22, 2026 08:53
Triggering scenario: `rustmotion render deck.json -o out.mp4 --watch` left open for an afternoon, with an `image` component pointing at `logo.png`. The author re-exports `logo.png`. `ASSET_CACHE` is keyed on the path alone (image.rs:41-54) with no mtime or size component, and in the incremental branch `clear_asset_cache()` only runs when the video config hash changes (resolution/fps) — editing scene content never clears it. Every subsequent re-render silently re-uses the stale decoded bitmap; the author sees the old logo indefinitely with nothing on stderr. The adjacent audio path solved exactly this and documents why (`encode/audio_analysis.rs:29-39`: fingerprint on len+mtime because 'someone re-exports a mix while the studio is open') — the image/GIF/video caches never got the same treatment. Memory side: `clear_asset_cache` touches only `ASSET_CACHE`; `GIF_CACHE`, `VIDEO_FRAME_CACHE` and `AUDIO_ANALYSIS_CACHE` have no clear function at all, so a long `--watch` session that touches several asset variants accumulates every decode for the process lifetime. Refs #220
LeadcodeDev
force-pushed
the
fix/watch-cache-invalidation
branch
from
September 22, 2026 09:00
b02296e to
523f995
Compare
LeadcodeDev
added a commit
that referenced
this pull request
Sep 22, 2026
Triggering scenario: `rustmotion render deck.json -o out.mp4 --watch` left open for an afternoon, with an `image` component pointing at `logo.png`. The author re-exports `logo.png`. `ASSET_CACHE` is keyed on the path alone (image.rs:41-54) with no mtime or size component, and in the incremental branch `clear_asset_cache()` only runs when the video config hash changes (resolution/fps) — editing scene content never clears it. Every subsequent re-render silently re-uses the stale decoded bitmap; the author sees the old logo indefinitely with nothing on stderr. The adjacent audio path solved exactly this and documents why (`encode/audio_analysis.rs:29-39`: fingerprint on len+mtime because 'someone re-exports a mix while the studio is open') — the image/GIF/video caches never got the same treatment. Memory side: `clear_asset_cache` touches only `ASSET_CACHE`; `GIF_CACHE`, `VIDEO_FRAME_CACHE` and `AUDIO_ANALYSIS_CACHE` have no clear function at all, so a long `--watch` session that touches several asset variants accumulates every decode for the process lifetime. Refs #220
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.
Severity Low, category coherence. Location:
crates/rustmotion/src/cli/commands/render.rs:452Impact
Triggering scenario:
rustmotion render deck.json -o out.mp4 --watchleft open for an afternoon, with animagecomponent pointing atlogo.png. The author re-exportslogo.png.ASSET_CACHEis keyed on the path alone (image.rs:41-54) with no mtime or size component, and in the incremental branchclear_asset_cache()only runs when the video config hash changes (resolution/fps) — editing scene content never clears it. Every subsequent re-render silently re-uses the stale decoded bitmap; the author sees the old logo indefinitely with nothing on stderr. The adjacent audio path solved exactly this and documents why (encode/audio_analysis.rs:29-39: fingerprint on len+mtime because 'someone re-exports a mix while the studio is open') — the image/GIF/video caches never got the same treatment. Memory side:clear_asset_cachetouches onlyASSET_CACHE;GIF_CACHE,VIDEO_FRAME_CACHEandAUDIO_ANALYSIS_CACHEhave no clear function at all, so a long--watchsession that touches several asset variants accumulates every decode for the process lifetime.Fix
Key
ASSET_CACHE/GIF_CACHE/VIDEO_FRAME_CACHEon(path, len, mtime)the waysource_fingerprintalready does for audio, or add aclear_all_caches()invoked at the top of every watch iteration. The first is strictly better: it keeps incremental reuse for untouched assets.Evidence the audit read
Part of the September 2026 audit remediation chantier. Refs #220 (RM-25).