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) + }) })