om-memory-system 3.7.0-next.47 → 3.7.0-next.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -59,6 +59,8 @@ export declare const START_LOCK_STALE_MS = 20000;
|
|
|
59
59
|
export declare function startLockPath(home?: string): string;
|
|
60
60
|
/** Lock files are private to the user (0600 in a 0700 folder), like the token file. */
|
|
61
61
|
export declare const nodeLockFs: LockFs;
|
|
62
|
+
/** `renameSync` that retries while Windows reports the target busy. */
|
|
63
|
+
export declare function renameRetrying(from: string, to: string, rename?: (from: string, to: string) => void, platform?: NodeJS.Platform, wait?: (ms: number) => void): void;
|
|
62
64
|
/** Remove the start lock when it names `pid`. A restart copy calls this once it owns the port. */
|
|
63
65
|
export declare function removeStartLockFor(pid: number, path?: string, lockFs?: LockFs): void;
|
|
64
66
|
/** What taking the start lock needs; a test drives two callers through it step by step. */
|
|
@@ -61,9 +61,30 @@ export const nodeLockFs = {
|
|
|
61
61
|
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
62
62
|
const temp = `${path}.${process.pid}.tmp`;
|
|
63
63
|
writeFileSync(temp, text, { mode: 0o600 });
|
|
64
|
-
|
|
64
|
+
renameRetrying(temp, path);
|
|
65
65
|
},
|
|
66
66
|
};
|
|
67
|
+
// Windows refuses to rename over a file another process has open, even for a
|
|
68
|
+
// moment. Readers hold the lock only while they read it, so a short retry wins.
|
|
69
|
+
const RENAME_RETRY_WAITS_MS = [1, 2, 5, 10, 20, 50, 100, 200];
|
|
70
|
+
const RENAME_BUSY_CODES = new Set(["EPERM", "EACCES", "EBUSY"]);
|
|
71
|
+
/** `renameSync` that retries while Windows reports the target busy. */
|
|
72
|
+
export function renameRetrying(from, to, rename = renameSync, platform = process.platform, wait = (ms) => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms)) {
|
|
73
|
+
for (let attempt = 0;; attempt++) {
|
|
74
|
+
try {
|
|
75
|
+
rename(from, to);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
const code = error.code;
|
|
80
|
+
const waitMs = RENAME_RETRY_WAITS_MS[attempt];
|
|
81
|
+
if (platform !== "win32" || !code || !RENAME_BUSY_CODES.has(code) || waitMs === undefined) {
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
wait(waitMs);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
67
88
|
/** Remove the start lock when it names `pid`. A restart copy calls this once it owns the port. */
|
|
68
89
|
export function removeStartLockFor(pid, path = startLockPath(), lockFs = nodeLockFs) {
|
|
69
90
|
try {
|