From 6656baaea32be196dd97b93a283a0e6d02b170ab Mon Sep 17 00:00:00 2001 From: Victor Sumner <308886+vsumner@users.noreply.github.com> Date: Tue, 24 Mar 2026 21:12:00 -0400 Subject: [PATCH] fix(cafs): update locker cache when file exists with correct integrity (#11085) * fix(cafs): update locker cache when file exists with correct integrity The CAS locker cache was not updated when a file already existed on disk with correct integrity. This caused repeated verifyFileIntegrity calls on subsequent lookups within the same process, adding unnecessary I/O. * fix(test): assert locker cache value not just key existence Strengthen the test to verify locker.get() returns the correct checkedAt timestamp, not just that the key exists. --- .changeset/fix-cafs-locker-cache.md | 6 ++++++ store/cafs/src/writeBufferToCafs.ts | 4 +++- store/cafs/test/writeBufferToCafs.test.ts | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 .changeset/fix-cafs-locker-cache.md diff --git a/.changeset/fix-cafs-locker-cache.md b/.changeset/fix-cafs-locker-cache.md new file mode 100644 index 0000000000..247f7caf97 --- /dev/null +++ b/.changeset/fix-cafs-locker-cache.md @@ -0,0 +1,6 @@ +--- +"@pnpm/store.cafs": patch +"pnpm": patch +--- + +Fix a bug where the CAS locker cache was not updated when a file already existed with correct integrity, causing repeated integrity re-verification on subsequent lookups within the same process. diff --git a/store/cafs/src/writeBufferToCafs.ts b/store/cafs/src/writeBufferToCafs.ts index 1d9e557aeb..183731723f 100644 --- a/store/cafs/src/writeBufferToCafs.ts +++ b/store/cafs/src/writeBufferToCafs.ts @@ -29,8 +29,10 @@ export function writeBufferToCafs ( // However, there is no way to find which package index file references // the given file. So we should revalidate the content of the file again. if (existsSame(fileDest, integrity)) { + const checkedAt = Date.now() + locker.set(fileDest, checkedAt) return { - checkedAt: Date.now(), + checkedAt, filePath: fileDest, } } diff --git a/store/cafs/test/writeBufferToCafs.test.ts b/store/cafs/test/writeBufferToCafs.test.ts index a85c8f3dee..af24a9fad3 100644 --- a/store/cafs/test/writeBufferToCafs.test.ts +++ b/store/cafs/test/writeBufferToCafs.test.ts @@ -17,4 +17,27 @@ describe('writeBufferToCafs', () => { writeBufferToCafs(new Map(), storeDir, buffer, fileDest, 420, { digest, algorithm: 'sha512' }) expect(fs.readFileSync(fullFileDest, 'utf8')).toBe('abc') }) + + it('should populate the locker cache when a file already exists with correct integrity', () => { + const storeDir = temporaryDirectory() + const fileDest = 'abc' + const buffer = Buffer.from('abc') + const digest = crypto.hash('sha512', buffer, 'hex') + const integrity = { digest, algorithm: 'sha512' } + const locker = new Map() + + // First write creates the file + writeBufferToCafs(locker, storeDir, buffer, fileDest, 420, integrity) + // Clear the locker to simulate a fresh lookup + locker.clear() + + // Second call should find the file on disk and cache it + const result = writeBufferToCafs(locker, storeDir, buffer, fileDest, 420, integrity) + const fullFileDest = path.join(storeDir, fileDest) + expect(locker.get(fullFileDest)).toBe(result.checkedAt) + + // Third call should return from locker cache without hitting disk + const cached = writeBufferToCafs(locker, storeDir, buffer, fileDest, 420, integrity) + expect(cached.checkedAt).toBe(result.checkedAt) + }) })