mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-06 08:14:04 -04:00
fix: guard MetadataCache methods against use after close
Add early-return guards to getHeaders, getIndex, getManifest, and updateCachedAt when the DB has been closed. This prevents "statement has been finalized" errors when the process exit handler closes the DB while async operations are still in flight. Also change store controller close to flush (not close) the metadata DB, since the exit handler handles cleanup.
This commit is contained in:
4
cache/metadata/src/index.ts
vendored
4
cache/metadata/src/index.ts
vendored
@@ -184,6 +184,7 @@ export class MetadataCache {
|
||||
* Cheap — no manifest data touched.
|
||||
*/
|
||||
getHeaders (name: string): MetadataHeaders | undefined {
|
||||
if (this.closed) return undefined
|
||||
const pending = this.findPendingIndex(name)
|
||||
if (pending) {
|
||||
return {
|
||||
@@ -204,6 +205,7 @@ export class MetadataCache {
|
||||
* Does NOT load per-version manifests — very cheap.
|
||||
*/
|
||||
getIndex (name: string): MetadataIndex | null {
|
||||
if (this.closed) return null
|
||||
const pending = this.findPendingIndex(name)
|
||||
if (pending) {
|
||||
return {
|
||||
@@ -238,6 +240,7 @@ export class MetadataCache {
|
||||
* Get a single version's manifest. Falls back from requested type to 'full'.
|
||||
*/
|
||||
getManifest (name: string, version: string, type: string): string | null {
|
||||
if (this.closed) return null
|
||||
const pending = this.findPendingManifest(name, version, type)
|
||||
if (pending) return pending.manifest
|
||||
const row = sqliteRetry(() => this.stmtGetManifest.get(name, version, type, type)) as { manifest: string } | undefined
|
||||
@@ -297,6 +300,7 @@ export class MetadataCache {
|
||||
* Update cachedAt without rewriting data.
|
||||
*/
|
||||
updateCachedAt (name: string, cachedAt: number): void {
|
||||
if (this.closed) return
|
||||
sqliteRetry(() => {
|
||||
this.stmtUpdateCachedAt.run(cachedAt, name)
|
||||
})
|
||||
|
||||
@@ -141,7 +141,7 @@ export async function createNewStoreController (
|
||||
const origClose = ctrl.close.bind(ctrl)
|
||||
ctrl.close = async () => {
|
||||
await origClose()
|
||||
metadataDb.close()
|
||||
metadataDb.flush()
|
||||
}
|
||||
return {
|
||||
ctrl,
|
||||
|
||||
Reference in New Issue
Block a user