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.
This commit is contained in:
Victor Sumner
2026-03-24 21:12:00 -04:00
committed by GitHub
parent f8e6774273
commit 6656baaea3
3 changed files with 32 additions and 1 deletions

View File

@@ -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.

View File

@@ -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,
}
}

View File

@@ -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<string, number>()
// 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)
})
})