Keep another process's downloads when opening a library (closes #105)
check / check (push) Successful in 1m18s
check / check (push) Successful in 1m18s
The download writer's temp files are now named .quak-<pid>-<random>.tmp. removeLeftoverTempFiles moves from the backup into the download module and deletes a .quak-*.tmp file only when the process ID in its name is no longer running; the content cache calls it at open() instead of deleting every temp file, so a download in progress in another process sharing the cache survives. The README backup layout and TODO.md are updated. Model: opus-5-5
This commit was merged in pull request #120.
This commit is contained in:
@@ -33,6 +33,7 @@ import {
|
||||
mkdirSync,
|
||||
statSync,
|
||||
} from "node:fs";
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
@@ -161,15 +162,28 @@ describe("ContentCache.open", () => {
|
||||
expect(statSync(thumbnails).mode & 0o777).toBe(0o700);
|
||||
});
|
||||
|
||||
it("reaps orphan temp files but keeps complete content", async () => {
|
||||
it("removes temp files of an exited process, keeping those of a running one and complete content", async () => {
|
||||
const originals = join(cacheDir, "originals");
|
||||
const thumbnails = join(cacheDir, "thumbnails");
|
||||
mkdirSync(originals, { recursive: true });
|
||||
mkdirSync(thumbnails, { recursive: true });
|
||||
const orphan = join(originals, ".quak-abc123.tmp");
|
||||
// A child that has already exited: its process ID is not running.
|
||||
const exitedPID = spawnSync(process.execPath, ["-e", ""]).pid;
|
||||
const orphan = join(originals, `.quak-${exitedPID}-abc123.tmp`);
|
||||
const orphanThumb = join(thumbnails, `.quak-${exitedPID}-abc456.tmp`);
|
||||
// This test's own process stands in for another process still
|
||||
// downloading into the same cache.
|
||||
const inProgress = join(originals, `.quak-${process.pid}-def123.tmp`);
|
||||
const inProgressThumb = join(
|
||||
thumbnails,
|
||||
`.quak-${process.pid}-def456.tmp`,
|
||||
);
|
||||
const complete = join(originals, "1.jpg");
|
||||
const thumb = join(thumbnails, "2.jpg");
|
||||
writeFileSync(orphan, "half-written");
|
||||
writeFileSync(orphanThumb, "half-written");
|
||||
writeFileSync(inProgress, "half-written");
|
||||
writeFileSync(inProgressThumb, "half-written");
|
||||
writeFileSync(complete, "whole");
|
||||
writeFileSync(thumb, "whole-thumb");
|
||||
|
||||
@@ -177,8 +191,12 @@ describe("ContentCache.open", () => {
|
||||
await cache.open();
|
||||
|
||||
expect(existsSync(orphan)).toBe(false);
|
||||
expect(existsSync(orphanThumb)).toBe(false);
|
||||
expect(existsSync(inProgress)).toBe(true);
|
||||
expect(existsSync(inProgressThumb)).toBe(true);
|
||||
expect(existsSync(complete)).toBe(true);
|
||||
expect(existsSync(thumb)).toBe(true);
|
||||
expect(cache.pathsFor(1)).toEqual({ originalPath: complete });
|
||||
});
|
||||
|
||||
it("records already-cached files so their paths appear in pathsFor", async () => {
|
||||
|
||||
Reference in New Issue
Block a user