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());
|
||||
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) {
|
||||
|
||||
@@ -99,6 +99,18 @@ describe("writeCoalesced", () => {
|
||||
|
||||
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", () => {
|
||||
|
||||
Reference in New Issue
Block a user