Skip to content

Commit f534772

Browse files
committed
fix(studio-server): a history lock that cannot be read fails the open instead of spinning
1 parent 20ad93b commit f534772

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

‎packages/studio-server/src/history/ownerLock.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ function ownerOf(file: string): number | null {
2424
try {
2525
const text = readFileSync(file, "utf-8");
2626
return /^\d+$/.test(text) ? Number(text) : Number.NaN;
27-
} catch {
28-
return null;
27+
} catch (error) {
28+
if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
29+
throw error;
2930
}
3031
}
3132

@@ -50,9 +51,8 @@ function releaseOwn(file: string): void {
5051
}
5152

5253
/**
53-
* Removes a dead owner's lock. One evictor at a time, re-reading the owner under its own lock, so a lock a live
54-
* process took after the caller's check survives. False when another evictor is at it. ponytail: an evictor that
55-
* dies mid-eviction leaves its lock to the next one that finds it dead, unguarded.
54+
* Removes a dead owner's lock under an evict lock, re-reading the owner, so a live owner's lock survives. False when
55+
* another evictor holds it. ponytail: a crashed evictor's lock is cleared unguarded; racing that can give two owners.
5656
*/
5757
function evictDeadOwner(file: string): boolean {
5858
const evictor = `${file}.evict`;

‎packages/studio-server/src/history/projectHistory.test.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,15 @@ describe("openProjectHistory", () => {
235235
);
236236
});
237237

238+
it("fails an open whose lock cannot be read, instead of retrying it forever", async () => {
239+
const { history, projectDir, historyRoot } = await project({ "index.html": "v1" });
240+
await history.close();
241+
mkdirSync(join(historyRoot, history.projectId, "owner.pid"));
242+
await expect(openProjectHistory({ projectDir, historyRoot, ownerWaitMs: 0 })).rejects.toThrow(
243+
/EISDIR/,
244+
);
245+
});
246+
238247
it("takes over a lock file that holds no pid", async () => {
239248
const { history, projectDir, historyRoot } = await project({ "index.html": "v1" });
240249
await history.close();

0 commit comments

Comments
 (0)