Skip to content

Commit 57f62c9

Browse files
committed
fix: tighten flagged storage read retries
(cherry picked from commit b5dfcaf)
1 parent 80a41ad commit 57f62c9

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

lib/storage/flagged-storage-file.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { FlaggedAccountStorageV1 } from "../storage.js";
22
import { sleep } from "../utils.js";
33

4-
const RETRYABLE_READ_CODES = new Set(["EBUSY", "EPERM", "EAGAIN"]);
4+
const RETRYABLE_READ_CODES = new Set(["EBUSY", "EAGAIN"]);
55

66
function isRetryableReadError(error: unknown): boolean {
77
const code = (error as NodeJS.ErrnoException | undefined)?.code;

test/storage-flagged.test.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -541,9 +541,6 @@ describe("flagged account storage", () => {
541541
});
542542

543543

544-
import { loadFlaggedAccountsFromFile } from "../lib/storage/flagged-storage-file.js";
545-
import { describeFlaggedSnapshot } from "../lib/storage/snapshot-inspectors.js";
546-
547544
describe("flagged storage extracted helpers", () => {
548545
it("retries transient Windows read locks before parsing", async () => {
549546
const normalizeFlaggedStorage = vi.fn((data) => data as never);
@@ -563,6 +560,42 @@ describe("flagged storage extracted helpers", () => {
563560
expect(normalizeFlaggedStorage).toHaveBeenCalledWith({ version: 1, accounts: [] });
564561
});
565562

563+
it("rethrows after retry budget is exhausted for windows lock errors", async () => {
564+
const sleep = vi.fn(async () => {});
565+
const readFile = vi
566+
.fn()
567+
.mockRejectedValue(Object.assign(new Error("locked"), { code: "EBUSY" }));
568+
await expect(
569+
loadFlaggedAccountsFromFile("flagged.json", {
570+
readFile,
571+
normalizeFlaggedStorage: vi.fn(),
572+
sleep,
573+
}),
574+
).rejects.toThrow("locked");
575+
expect(readFile).toHaveBeenCalledTimes(4);
576+
expect(sleep).toHaveBeenNthCalledWith(1, 10);
577+
expect(sleep).toHaveBeenNthCalledWith(2, 20);
578+
expect(sleep).toHaveBeenNthCalledWith(3, 40);
579+
});
580+
581+
it("rethrows after retry budget is exhausted for windows lock errors", async () => {
582+
const sleep = vi.fn(async () => {});
583+
const readFile = vi
584+
.fn()
585+
.mockRejectedValue(Object.assign(new Error("locked"), { code: "EBUSY" }));
586+
await expect(
587+
loadFlaggedAccountsFromFile("flagged.json", {
588+
readFile,
589+
normalizeFlaggedStorage: vi.fn(),
590+
sleep,
591+
}),
592+
).rejects.toThrow("locked");
593+
expect(readFile).toHaveBeenCalledTimes(4);
594+
expect(sleep).toHaveBeenNthCalledWith(1, 10);
595+
expect(sleep).toHaveBeenNthCalledWith(2, 20);
596+
expect(sleep).toHaveBeenNthCalledWith(3, 40);
597+
});
598+
566599
it("propagates malformed JSON parse errors", async () => {
567600
await expect(
568601
loadFlaggedAccountsFromFile("flagged.json", {

0 commit comments

Comments
 (0)