Fix two intermittently failing library tests (closes #90)
check / check (push) Successful in 27s
check / check (push) Successful in 27s
Library.close() now returns a promise that resolves once the work it started has finished: an in-flight refresh with its cache write, the ML data fetch, and running precache sweeps. The interval test could see a refresh's new state, close, and remove the directory while the write was still running. Every library test and CLI command now awaits close(), and tests hold each of the three writes open to prove close() waits for it. The precache test waited for its stub source to be called, but the cache records a file only after checking it on disk, so status() could lag. It now waits for both fills to report "done". Model: opus-5-5
This commit was merged in pull request #92.
This commit is contained in:
+16
-12
@@ -92,9 +92,10 @@ export class Precache {
|
||||
private pinned = new Set<number>();
|
||||
|
||||
// A sweep runs at most once per fill at a time; a re-kick while one runs is
|
||||
// a no-op, and the next refresh re-kicks after it finishes.
|
||||
private thumbRunning = false;
|
||||
private originalsRunning = false;
|
||||
// a no-op, and the next refresh re-kicks after it finishes. Each holds the
|
||||
// running sweep, so `close()` can wait for it.
|
||||
private thumbSweep?: Promise<void>;
|
||||
private originalsSweep?: Promise<void>;
|
||||
private readonly aborter = new AbortController();
|
||||
private closed = false;
|
||||
|
||||
@@ -191,15 +192,19 @@ export class Precache {
|
||||
}
|
||||
|
||||
// Stop the fills. In-flight fetches are left to settle; queued ones drop.
|
||||
close(): void {
|
||||
// Resolves once both sweeps have finished, so nothing is still writing.
|
||||
async close(): Promise<void> {
|
||||
this.closed = true;
|
||||
this.aborter.abort();
|
||||
await Promise.all([
|
||||
this.thumbSweep?.catch(() => {}),
|
||||
this.originalsSweep?.catch(() => {}),
|
||||
]);
|
||||
}
|
||||
|
||||
private kickThumbnails(): void {
|
||||
if (this.thumbRunning) return;
|
||||
this.thumbRunning = true;
|
||||
void this.sweep(
|
||||
if (this.thumbSweep) return;
|
||||
this.thumbSweep = this.sweep(
|
||||
"precacheThumbnails",
|
||||
() => this.thumbOrder,
|
||||
(id) => this.cache!.pathsFor(id).thumbnailPath !== undefined,
|
||||
@@ -211,14 +216,13 @@ export class Precache {
|
||||
signal: this.aborter.signal,
|
||||
}),
|
||||
).finally(() => {
|
||||
this.thumbRunning = false;
|
||||
this.thumbSweep = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
private kickOriginals(): void {
|
||||
if (this.originalsRunning) return;
|
||||
this.originalsRunning = true;
|
||||
void this.sweep(
|
||||
if (this.originalsSweep) return;
|
||||
this.originalsSweep = this.sweep(
|
||||
"precacheOriginals",
|
||||
() => this.originalsOrder,
|
||||
(id) => this.cache!.pathsFor(id).originalPath !== undefined,
|
||||
@@ -229,7 +233,7 @@ export class Precache {
|
||||
signal: this.aborter.signal,
|
||||
}),
|
||||
).finally(() => {
|
||||
this.originalsRunning = false;
|
||||
this.originalsSweep = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user