Skip to content

Perf: reduce ingest-pipeline CPU/memory churn concurrent with playback [stacked on #113] - #118

Merged
sanylax0 merged 1 commit into
claude/repo-review-improvements-yvk3t7-cloud-importfrom
claude/repo-review-improvements-yvk3t7-ingest-perf
Jul 20, 2026
Merged

sanylax0 merged 1 commit into
claude/repo-review-improvements-yvk3t7-cloud-importfrom
claude/repo-review-improvements-yvk3t7-ingest-perf

Conversation

@sanylax2

Copy link
Copy Markdown
Collaborator

Part 3 of the CPU/memory audit — the background pipeline that runs while music plays. Stacked on #113/#112 (touches the same stems files). All changes behavior-identical.

  • Main-thread file opens eliminated. The ingest duration read and the launch-backfill duration read both did a synchronous AVAudioFile(forReading:) on the main actor — one per track at launch for a big library. Now off-main at utility priority.
  • Stem-cache budget passes single-flight. Every queue move fired a detached full-directory scan; rapid skips stacked N concurrent scans racing each other's evictions. Now one runs at a time with at most one queued follow-up, which re-reads the latest protected set when it starts (so the newest play-queue neighborhood is what's protected — strictly safer than before).
  • separateStems no longer pins the @Model track for the CPU-minutes separation run (weak capture; every write already guards on modelContext).
  • O(window) memmove churn removed from separation. runStreaming's mix buffers and StreamingOverlapAdd.drain used removeFirst(n) per window (~MBs of copy traffic each, concurrent with playback); both now use a head cursor with amortized compaction. The existing OverlapAddTests pin output equivalence on Linux CI.
  • Launch fetches stop hydrating beat grids. The queue-exhaustion/restore ID maps and LibraryCleanup's reference scans use propertiesToFetch, so beatTimes (hundreds of doubles per track) faults in only for tracks that actually play.

Device check

  • Play with separation in flight: stems still complete and link (watch stems logs); skip rapidly — no behavioral change, stems of the current neighborhood survive eviction.
  • Cold launch with a large library while playing: no UI hitches from the backfill; resume still lands correctly.

🤖 Generated with Claude Code

https://claude.ai/code/session_013TJoWkqg8bzkGdzxWhWjWP


Generated by Claude Code

Audit part 3 — behavior identical throughout:
- AVAudioFile duration reads (ingest + launch backfill) move off the main
  actor; a large library's backfill did one synchronous main-thread file
  open per track.
- Stem-cache budget passes are single-flight: rapid skips fired one full
  directory scan per queue move, racing each other. Coalesced to one
  running + at most one queued pass that re-reads the latest protected
  set when it starts.
- separateStems no longer strongly pins the @model track across the
  CPU-minutes separation task (weak capture; all writes already guard on
  modelContext).
- runStreaming mix buffers and StreamingOverlapAdd drain via a head
  cursor with amortized compaction instead of removeFirst-per-window
  memmoves (~MBs of copy traffic per window under playback).
- Launch/exhaustion id-map fetches and LibraryCleanup fetches use
  propertiesToFetch so every track's beatTimes array is no longer
  eagerly hydrated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013TJoWkqg8bzkGdzxWhWjWP
@sanylax0
sanylax0 merged commit 7f80c1f into claude/repo-review-improvements-yvk3t7-cloud-import Jul 20, 2026
4 checks passed
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