Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit b5a1b354a74db59e78ff596343ff157c303933cf
parent cd1c5dbea3a0baa6c23f762bad774bdbc17ee207
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Thu,  1 Oct 2026 22:10:35 -0400

common: the hook's media-side temp is scratch and a dead process's is swept (re-review R2)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Diffstat:
Mcommon/lib/mediaTier-server.test.ts | 13+++++++++++++
Mcommon/lib/mediaTier-server.ts | 11+++++++++++
Mcommon/lib/mediaTier.test.ts | 1+
Mcommon/lib/mediaTier.ts | 4+++-
4 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/common/lib/mediaTier-server.test.ts b/common/lib/mediaTier-server.test.ts @@ -325,3 +325,16 @@ test("removeMediaFile derefs a link into ANOTHER id's media dir (a renamed video await assert.rejects(lstat(path.join(f.videoDir, "audio.m4a"))); await rm(f.root, { recursive: true, force: true }); }); + +test("a dead process's half-placed bytes in media/<id>/ are swept with the video dir", async () => { + const f = await fixture(); + const tierDir = path.join(channelMediaLink(f.paths, f.slug), "vid1"); + await mkdir(tierDir, { recursive: true }); + await writeFile(path.join(tierDir, ".audio.mp3.tiering-999999"), "HALF"); + await tierVideoDir(f.videoDir); + assert.deepEqual( + (await readdir(tierDir)).filter((n) => n.includes("tiering")), + [], + ); + await rm(f.root, { recursive: true, force: true }); +}); diff --git a/common/lib/mediaTier-server.ts b/common/lib/mediaTier-server.ts @@ -288,6 +288,17 @@ export async function tierVideoDir( if (!isTierable(name)) continue; counts[await tierMediaFile(videoDir, name, opts)] += 1; } + // The media side's strays: bytes a dead process was placing + // (`.<name>.tiering-<pid>` in `media/<id>/`). Only while the tier answers. + const destDir = mediaDirOfVideoDir(videoDir); + if (await mediaTierReady(path.dirname(destDir))) { + for (const name of await readdir(destDir).catch(() => [] as string[])) { + const stray = /^\..+\.tiering-(\d+)$/.exec(name); + if (stray && !processAlive(Number(stray[1]))) { + await rm(path.join(destDir, name), { force: true }).catch(() => {}); + } + } + } return counts; } diff --git a/common/lib/mediaTier.test.ts b/common/lib/mediaTier.test.ts @@ -44,6 +44,7 @@ const TABLE: ReadonlyArray<[string, "media" | "text" | "scratch", boolean]> = [ ["audio.m4a.ytdl", "scratch", false], [".audio.mp3.parakeet", "scratch", false], [".audio.mp3.tierlink-4242", "scratch", false], + [".audio.mp3.tiering-4242", "scratch", false], // The hot text. ["transcript.json", "text", false], ["transcript.en.vtt", "text", false], diff --git a/common/lib/mediaTier.ts b/common/lib/mediaTier.ts @@ -59,8 +59,10 @@ const SCRATCH_PATTERNS: ReadonlyArray<RegExp> = [ // yt-dlp's resume-state file beside one (`audio.m4a.ytdl`). /\.part$/, /\.ytdl$/, - // The media-tier hook's own temp link (`lib/mediaTier-server.ts`). + // The media-tier hook's own temps (`lib/mediaTier-server.ts`): the link + // beside the name, and the bytes being placed in `media/<id>/`. /\.tierlink-\d+$/, + /\.tiering-\d+$/, ]; export function isScratchEntry(name: string): boolean {