music: staging-slot cache with atomic symlink swap for full reindex
Foundation for a safe from-scratch reindex. The live cache path is now a SYMLINK to a slot dir; readers + incremental writes follow it. - ensureCacheSetup() (run at sidecar boot): makes `cache` a symlink to a slot, migrating an existing real cache dir once (a fast rename, not a copy). - runBuild(outRoot, prev): the build now writes to a given root and returns the manifest without touching live serving state. - reindexNow(): incremental, in-place live build (manual + localized updates). - reindexFull(): builds a complete index into a FRESH slot without touching the live one, then activateSlot() swaps the symlink atomically (rename-over) ONLY on success — a failed rebuild leaves the live index untouched; old slots pruned. walk() takes the output root. Verified end-to-end: fresh setup, full build + swap + prune, incremental-through-symlink, and the one-time real-dir migration (content preserved). Restart officer-music to apply (triggers the migration). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { createSidecarConnector } from '../connect';
|
||||
import { streamAudioFile } from './stream-audio';
|
||||
import {
|
||||
reindexNow,
|
||||
ensureCacheSetup,
|
||||
getIndexStatus,
|
||||
getManifest,
|
||||
albumVersion,
|
||||
@@ -70,6 +71,9 @@ function getFreePort(): number {
|
||||
|
||||
const port = getFreePort();
|
||||
|
||||
// Ensure the cache is a symlink-to-slot before serving/building, so full reindexes can swap atomically.
|
||||
await ensureCacheSetup();
|
||||
|
||||
const server = Bun.serve({
|
||||
port,
|
||||
hostname: '127.0.0.1',
|
||||
|
||||
Reference in New Issue
Block a user