From 22cbc0fd45d00b88caa70b89e782ae92e63b0210 Mon Sep 17 00:00:00 2001 From: Luke Mino-Altherr Date: Tue, 3 Mar 2026 17:30:30 -0800 Subject: [PATCH] fix: acquire exclusive SQLite lock at startup to prevent multi-process DB conflicts When two ComfyUI processes share the same database file but point to different input/output/model directories, each process's scan marks the other's assets as missing, causing unreliable asset visibility. This adds an exclusive lock so the second process fails fast at startup with a clear message to use --database-url. Co-Authored-By: Claude Opus 4.6 --- app/database/db.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/database/db.py b/app/database/db.py index 2a79f7df0..dcc8783b2 100644 --- a/app/database/db.py +++ b/app/database/db.py @@ -15,6 +15,7 @@ try: from alembic.runtime.migration import MigrationContext from alembic.script import ScriptDirectory from sqlalchemy import create_engine, event + import sqlalchemy as sa from sqlalchemy.orm import sessionmaker _DB_AVAILABLE = True @@ -76,13 +77,25 @@ def init_db(): # Check if we need to upgrade engine = create_engine(db_url) - # Enable foreign key enforcement for SQLite + # Enable foreign key enforcement and exclusive locking for SQLite @event.listens_for(engine, "connect") def set_sqlite_pragma(dbapi_connection, connection_record): cursor = dbapi_connection.cursor() cursor.execute("PRAGMA foreign_keys=ON") + cursor.execute("PRAGMA locking_mode=EXCLUSIVE") cursor.close() + + # Acquire the exclusive lock early by opening a connection and triggering a read. + # This prevents two processes from sharing the same database file. conn = engine.connect() + try: + conn.execute(sa.text("PRAGMA schema_version")) + except Exception: + raise RuntimeError( + f"Could not acquire exclusive lock on database '{db_path}'. " + "Another ComfyUI process may already be using it. " + "Use --database-url to specify a separate database file." + ) context = MigrationContext.configure(conn) current_rev = context.get_current_revision()