mirror of
https://github.com/Nystik-gh/ignis.git
synced 2026-06-17 04:35:53 +00:00
tolerate a concurrent delete during the post-write stat
This commit is contained in:
@@ -31,9 +31,19 @@ async function writeToDisk(absPath, data, encoding) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
lastWriteTime.set(absPath, Date.now());
|
lastWriteTime.set(absPath, Date.now());
|
||||||
const stat = await fs.promises.stat(absPath);
|
|
||||||
|
|
||||||
return { mtime: stat.mtimeMs, size: stat.size };
|
// A concurrent delete can remove the file between the write and the stat (a rapid write-then-delete on the same path).
|
||||||
|
// The write itself succeeds, so report synthetic metadata rather than failing the request on the now-missing file.
|
||||||
|
try {
|
||||||
|
const stat = await fs.promises.stat(absPath);
|
||||||
|
return { mtime: stat.mtimeMs, size: stat.size };
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code === "ENOENT") {
|
||||||
|
return { mtime: Date.now(), size: estimateSize(data, encoding) };
|
||||||
|
}
|
||||||
|
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function flushEntry(absPath) {
|
function flushEntry(absPath) {
|
||||||
|
|||||||
@@ -99,6 +99,18 @@ describe("writeCoalesced", () => {
|
|||||||
|
|
||||||
expect(elapsed).toBeLessThan(20);
|
expect(elapsed).toBeLessThan(20);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("returns synthetic metadata when the file is deleted before the post-write stat", async () => {
|
||||||
|
const filePath = path.join(tmpDir, "race.txt");
|
||||||
|
vi.spyOn(fs.promises, "stat").mockRejectedValueOnce(
|
||||||
|
Object.assign(new Error("ENOENT"), { code: "ENOENT" }),
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await coalescer.writeCoalesced(filePath, "hello", "utf-8");
|
||||||
|
|
||||||
|
expect(result.size).toBe(5);
|
||||||
|
expect(result.mtime).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getPending", () => {
|
describe("getPending", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user