refactor(shared-manager): tighten canonical identity capture

Build the canonical identity from the stat getCanonicalFile already
takes, instead of a second lstat of the same inode. One syscall less,
and mode, mtime and identity now describe the same moment rather than
two adjacent ones.

Assert in the adoption race tests that the foreign writer never fired.
It writes only when the canonical path is observed empty, so a zero
count states the invariant the fix establishes - the path is never left
without a regular file - instead of only checking the final content.

Built [OnSteroids](https://onsteroids.ai)
This commit is contained in:
Sergey Galuza committed 2026-08-23 08:32:39 +02:00
1 parent 00a4dceb94
commit fa3fd8eb3a
2 files changed
+10 -10

No files matched your search

@@ -148,9 +148,7 @@ interface CanonicalIdentity {
size: number;
}
function readCanonicalIdentity(writePath: string): CanonicalIdentity | null {
const stats = getLstatSync(writePath);
if (!stats?.isFile()) return null;
function canonicalIdentityOf(stats: fs.Stats): CanonicalIdentity {
return { ino: stats.ino, mtimeMs: stats.mtimeMs, size: stats.size };
}
@@ -246,9 +244,7 @@ function publishCanonicalContent(
descriptor = null;
const currentStats = getLstatSync(writePath);
const current = currentStats?.isFile()
? { ino: currentStats.ino, mtimeMs: currentStats.mtimeMs, size: currentStats.size }
: null;
const current = currentStats?.isFile() ? canonicalIdentityOf(currentStats) : null;
if (!canonicalIdentityMatches(expected, current)) {
throw Object.assign(new TypeError(`Canonical file changed during adoption: ${writePath}`), {
code: 'EEXIST',
@@ -297,12 +293,12 @@ function getCanonicalFile(canonicalPath: string): {
});
}
// Identity first: a write landing between the two reads leaves us holding
// newer bytes than the identity describes, and publication fails closed.
const identity = readCanonicalIdentity(writePath);
// The identity describes the inode as of the stat above, taken before the
// content read: a write landing in between leaves us holding newer bytes
// than the identity describes, and publication fails closed.
return {
content: fs.readFileSync(writePath),
identity,
identity: canonicalIdentityOf(canonicalStats),
mode: canonicalStats.mode & 0o777,
mtimeMs: canonicalStats.mtimeMs,
writePath,
+4
View File
@@ -686,6 +686,10 @@ describe('SharedManager', () => {
foreignWriter.restore();
}
// The writer only fires when the canonical path is observed empty, so
// zero writes is the invariant itself: adoption never left the path
// without a regular file.
expect(foreignWriter.placeholderWrites()).toBe(0);
expect(fs.existsSync(canonicalPath)).toBe(true);
expect(fs.readFileSync(canonicalPath, 'utf8')).not.toBe(placeholder);
expect([divergedSettings, previousSettings]).toContainEqual(readJson(canonicalPath));