fix(assets): clean temp files at startup when assets are disabled (D9)

This commit is contained in:
Simon Pinfold
2026-08-26 03:07:44 -07:00
parent 33be00c57e
commit 2947eec3c2
3 changed files with 52 additions and 3 deletions

View File

@@ -124,6 +124,20 @@ def run_asset_startup() -> None:
start_asset_seeder()
def run_startup(*, enable_assets: bool) -> None:
"""Startup temp maintenance entry point, owning the enabled/disabled policy.
Enabled: full asset startup (DB temp-row wipe -> filesystem sweep -> seeder), which
intentionally orders row deletion before filesystem deletion and skips the sweep when
the wipe fails. Disabled: filesystem sweep only (master parity -- master called
cleanup_temp() unconditionally); with assets off there are no asset rows to wipe.
"""
if enable_assets:
run_asset_startup()
else:
cleanup_temp_filesystem()
def run_asset_shutdown_cleanup() -> None:
with create_session() as session:
wipe_temp_db_rows(session)

View File

@@ -478,14 +478,13 @@ def hijack_progress(server_instance):
def setup_database():
from app.assets import mode
from app.assets.lifecycle import init_db_and_state, run_asset_startup
from app.assets.lifecycle import init_db_and_state, run_startup
try:
if dependencies_available():
mode.init(args)
init_db_and_state()
if args.enable_assets:
run_asset_startup()
run_startup(enable_assets=args.enable_assets)
except Exception as e:
if "database is locked" in str(e):
logging.error(

View File

@@ -15,6 +15,7 @@ from app.assets.lifecycle import (
get_excluded_scan_roots,
run_asset_shutdown_cleanup,
run_asset_startup,
run_startup,
wipe_temp_db_rows,
)
from app.assets.scanner import get_temp_prefixes, sync_temp_references_safely
@@ -103,6 +104,41 @@ def test_db_wipe_failure_skips_rmtree_and_continues(mock_create_session):
seeder_mock.assert_called_once()
def test_run_startup_disabled_sweeps_temp_filesystem_without_db_work(comfy_dirs):
"""D9 — Given assets disabled and a stale temp file, When run_startup runs, Then the
filesystem sweep removes it and no DB-row wipe or seeder work happens (master parity:
master called cleanup_temp() unconditionally; with assets off there are no rows to wipe)."""
stale = comfy_dirs / "stale.png"
stale.write_bytes(b"\x00" * 10)
assert stale.exists()
with (
patch("app.assets.lifecycle.run_asset_startup") as asset_startup_mock,
patch("app.assets.lifecycle.wipe_temp_db_rows") as wipe_mock,
patch("app.assets.lifecycle.start_asset_seeder") as seeder_mock,
):
run_startup(enable_assets=False)
assert not stale.exists()
asset_startup_mock.assert_not_called()
wipe_mock.assert_not_called()
seeder_mock.assert_not_called()
def test_run_startup_enabled_delegates_to_asset_startup_not_bare_sweep():
"""D9 — Given assets enabled, When run_startup runs, Then it delegates to the ordered
run_asset_startup (sole owner of DB-row-before-filesystem deletion) and never calls the
bare filesystem sweep directly, so S12's enabled-path ordering is preserved."""
with (
patch("app.assets.lifecycle.run_asset_startup") as asset_startup_mock,
patch("app.assets.lifecycle.cleanup_temp_filesystem") as cleanup_mock,
):
run_startup(enable_assets=True)
asset_startup_mock.assert_called_once_with()
cleanup_mock.assert_not_called()
def test_rmtree_failure_excludes_temp_from_scan(session, comfy_dirs, mock_create_session):
record_id, content_id = _seed_temp_rows(session, comfy_dirs)