fix(cache): close the connection the schema init opened

`with sqlite3.Connection` ends the transaction but keeps the file handle open,
so every cache class leaked one handle per instance until the garbage collector
happened to run. On Windows that makes the database file undeletable while the
process lives (WinError 32), which broke 30 cache tests in teardown and would
also block moving or clearing a cache at runtime.

All eight `with <connection>` sites now go through `closing_connection()`, and a
regression test asserts the schema init leaves no usable connection behind.
This commit is contained in:
Will Miao
2026-10-12 11:35:14 +08:00
parent 5fbac84910
commit fd40cd952b
7 changed files with 61 additions and 11 deletions
+5 -4
View File
@@ -17,6 +17,7 @@ from typing import Any, Dict, Iterable, Iterator, List, Mapping, Optional, Seque
from .errors import RateLimitError, ResourceNotFoundError
from .settings_manager import get_settings_manager
from ..utils.cache_db import closing_connection
from ..utils.cache_paths import CacheType, resolve_cache_path_with_migration
from ..utils.constants import MODEL_WEIGHT_FILE_TYPES
from ..utils.civitai_utils import rewrite_preview_url
@@ -445,7 +446,7 @@ class ModelUpdateService:
if self._schema_initialized:
return
try:
with self._connect() as conn:
with closing_connection(self._connect()) as conn:
conn.execute("PRAGMA journal_mode=WAL")
conn.execute("PRAGMA foreign_keys = ON")
conn.executescript(self._SCHEMA)
@@ -484,7 +485,7 @@ class ModelUpdateService:
return
try:
with sqlite3.connect(legacy_path, check_same_thread=False) as legacy_conn:
with closing_connection(sqlite3.connect(legacy_path, check_same_thread=False)) as legacy_conn:
legacy_conn.row_factory = sqlite3.Row
status_rows = legacy_conn.execute(
"""
@@ -2315,7 +2316,7 @@ class ModelUpdateService:
status_rows: list[sqlite3.Row] = []
version_rows: list[sqlite3.Row] = []
with self._connect() as conn:
with closing_connection(self._connect()) as conn:
for start in range(0, len(ids), self._SQLITE_MAX_VARIABLES):
chunk = tuple(ids[start : start + self._SQLITE_MAX_VARIABLES])
placeholders = ",".join("?" for _ in chunk)
@@ -2418,7 +2419,7 @@ class ModelUpdateService:
record.last_checked_at,
1 if record.should_ignore_model else 0,
)
with self._connect() as conn:
with closing_connection(self._connect()) as conn:
conn.execute(
"""
INSERT INTO model_update_status (