Skip to content

test(producer): extract frameDirMaxIndexCache to its own module and pin cross-job isolation#381

Open
vanceingalls wants to merge 1 commit intovance/streaming-encoder-lifecycle-testsfrom
vance/frame-dir-cache-isolation-tests
Open

test(producer): extract frameDirMaxIndexCache to its own module and pin cross-job isolation#381
vanceingalls wants to merge 1 commit intovance/streaming-encoder-lifecycle-testsfrom
vance/frame-dir-cache-isolation-tests

Conversation

@vanceingalls
Copy link
Copy Markdown
Collaborator

@vanceingalls vanceingalls commented Apr 21, 2026

Summary

Extract the frameDirMaxIndexCache from a private module-scoped Map inside renderOrchestrator.ts into its own frameDirCache.ts module, then add a 11-test bun:test suite that pins the cross-job isolation contract added in Chunk 5B.

Why

Chunk 9E of plans/hdr-followups.md. The cache lived as a private Map inside renderOrchestrator.ts, which made the cross-job isolation contract from Chunk 5B impossible to unit-test directly. Extracting it both makes the contract testable and reduces orchestrator complexity slightly.

What changed

  • New packages/producer/src/services/frameDirCache.ts exposes getMaxFrameIndex / clearMaxFrameIndex / getMaxFrameIndexCacheSize (plus a test-only __resetMaxFrameIndexCacheForTests helper). Behavior is unchanged: callers still get the same module-scoped sharing inside a job, and renderOrchestrator's outer finally still clears every entry it registered so the cache cannot grow monotonically across renders.
  • renderOrchestrator.ts: imports the new helpers, drops the unused readdirSync import, updates inline comments, and replaces two frameDirMaxIndexCache.delete sites with clearMaxFrameIndex.
  • New frameDirCache.test.ts (bun:test, 11 tests) covering:
    • Reading the max index from a populated directory.
    • Ignoring filenames that don't match frame_NNNN.png (wrong ext, wrong prefix, wrong case, double extension, empty index group, same-named subdirectory).
    • Empty- and missing-directory paths returning 0 and being cached.
    • Intra-job invariant: subsequent readdir mutations not observed once cached.
    • clearMaxFrameIndex forcing a re-read; returns false for paths that were never cached.
    • Per-directory isolation when multiple directories are registered.
    • The cross-job contract from Chunk 5B: cache empty between well-behaved jobs, doesn't grow monotonically across 20 simulated renders with 3 HDR videos each (steady-state cache size stays at 3), and a buggy job that forgets to clear leaks exactly its own entries rather than affecting unrelated jobs.

Test plan

  • frameDirCache.test.ts 11/11 pass.
  • Existing producer tests unchanged.
  • Behavior preserved: same module-scoped sharing inside a job, same outer-finally eviction.

Stack

Chunk 9E of plans/hdr-followups.md. Test-driven extraction; complements Chunk 5B.

Copy link
Copy Markdown
Collaborator Author

vanceingalls commented Apr 21, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from 04f1932 to d62dbc2 Compare April 22, 2026 22:13
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch 2 times, most recently from 76b62e3 to f47ae00 Compare April 22, 2026 22:52
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch 2 times, most recently from b171d31 to aefd2fc Compare April 22, 2026 23:26
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 1d25da7 to 18845b3 Compare April 23, 2026 00:05
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from aefd2fc to 3be90e5 Compare April 23, 2026 00:06
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 18845b3 to dcd6817 Compare April 23, 2026 00:10
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from 3be90e5 to ede0291 Compare April 23, 2026 00:10
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from dcd6817 to adc776e Compare April 23, 2026 00:45
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch 2 times, most recently from a4717db to c76bbb2 Compare April 23, 2026 01:58
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch 2 times, most recently from 143a1db to 6ece916 Compare April 23, 2026 02:58
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from c76bbb2 to 1cb6854 Compare April 23, 2026 02:58
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 6ece916 to e638a99 Compare April 23, 2026 03:21
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from 1cb6854 to adfcf6f Compare April 23, 2026 03:21
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from e638a99 to 5fb85c5 Compare April 23, 2026 03:42
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from adfcf6f to 56d9997 Compare April 23, 2026 03:43
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 5fb85c5 to d84c3ea Compare April 23, 2026 04:50
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from 56d9997 to b8fa66f Compare April 23, 2026 04:51
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from d84c3ea to 4b68ca4 Compare April 23, 2026 05:10
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from b8fa66f to d9a7c43 Compare April 23, 2026 05:11
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 4b68ca4 to 4be516a Compare April 23, 2026 05:46
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from d9a7c43 to dc034ec Compare April 23, 2026 05:46
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 4be516a to 5a225bf Compare April 23, 2026 06:07
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from dc034ec to 39201e6 Compare April 23, 2026 06:07
@vanceingalls vanceingalls force-pushed the vance/streaming-encoder-lifecycle-tests branch from 5a225bf to c7fcca8 Compare April 23, 2026 06:59
…in cross-job isolation

Chunk 9E. The frame-directory max-index cache lived as a private
module-scoped Map inside renderOrchestrator.ts, which made the cross-job
isolation contract added in Chunk 5B impossible to unit-test directly.

Extract the cache into packages/producer/src/services/frameDirCache.ts
behind getMaxFrameIndex / clearMaxFrameIndex / getMaxFrameIndexCacheSize
(plus a test-only __resetMaxFrameIndexCacheForTests helper). Behavior is
unchanged: callers still get the same module-scoped sharing inside a
job, and renderOrchestrator's outer finally still clears every entry it
registered so the cache cannot grow monotonically across renders.

renderOrchestrator now imports the new helpers, drops the unused
readdirSync import, and updates the inline comments to point at the new
module. Two cleanup sites that previously called
frameDirMaxIndexCache.delete now call clearMaxFrameIndex.

Add frameDirCache.test.ts (bun:test) with 11 tests covering:
  - reading the max index from a populated directory
  - ignoring filenames that do not match frame_NNNN.png (wrong ext,
    wrong prefix, wrong case, double extension, empty index group, and
    a same-named subdirectory)
  - empty- and missing-directory paths returning 0 and being cached
  - the intra-job invariant that subsequent readdir mutations are not
    observed once a directory has been cached
  - clearMaxFrameIndex forcing a re-read and returning false for paths
    that were never cached
  - per-directory isolation when multiple directories are registered
  - the cross-job contract from Chunk 5B: the cache is empty between
    well-behaved jobs, does not grow monotonically across 20 simulated
    renders with 3 HDR videos each (steady-state cache size stays at 3),
    and a buggy job that forgets to clear leaks exactly its own entries
    rather than affecting unrelated jobs.

Made-with: Cursor
@vanceingalls vanceingalls force-pushed the vance/frame-dir-cache-isolation-tests branch from 39201e6 to cdb1508 Compare April 23, 2026 06:59
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.

3 participants