mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
2a35d93a4d
**Service Dependencies** Services that depend on other services now access those services via the `Invoker` object. This object is provided to the service as a kwarg to its `start()` method. Until now, most services did not utilize this feature, and several services required their dependencies to be initialized and passed in on init. Additionally, _all_ services are now registered as invocation services - including the low-level services. This obviates issues with inter-dependent services we would otherwise experience as we add workflow storage. **Database Access** Previously, we were passing in a separate sqlite connection and corresponding lock as args to services in their init. A good amount of posturing was done in each service that uses the db. These objects, along with the sqlite startup and cleanup logic, is now abstracted into a simple `SqliteDatabase` class. This creates the shared connection and lock objects, enables foreign keys, and provides a `clean()` method to do startup db maintenance. This is not a service as it's only used by sqlite services.
47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
import sqlite3
|
|
import threading
|
|
from logging import Logger
|
|
|
|
from invokeai.app.services.config import InvokeAIAppConfig
|
|
|
|
|
|
class SqliteDatabase:
|
|
conn: sqlite3.Connection
|
|
lock: threading.Lock
|
|
_logger: Logger
|
|
_config: InvokeAIAppConfig
|
|
|
|
def __init__(self, config: InvokeAIAppConfig, logger: Logger):
|
|
self._logger = logger
|
|
self._config = config
|
|
|
|
if self._config.use_memory_db:
|
|
location = ":memory:"
|
|
logger.info("Using in-memory database")
|
|
else:
|
|
db_path = self._config.db_path
|
|
db_path.parent.mkdir(parents=True, exist_ok=True)
|
|
location = str(db_path)
|
|
self._logger.info(f"Using database at {location}")
|
|
|
|
self.conn = sqlite3.connect(location, check_same_thread=False)
|
|
self.lock = threading.Lock()
|
|
self.conn.row_factory = sqlite3.Row
|
|
|
|
if self._config.log_sql:
|
|
self.conn.set_trace_callback(self._logger.debug)
|
|
|
|
self.conn.execute("PRAGMA foreign_keys = ON;")
|
|
|
|
def clean(self) -> None:
|
|
try:
|
|
self.lock.acquire()
|
|
self.conn.execute("VACUUM;")
|
|
self.conn.commit()
|
|
self._logger.info("Cleaned database")
|
|
except Exception as e:
|
|
self._logger.error(f"Error cleaning database: {e}")
|
|
raise e
|
|
finally:
|
|
self.lock.release()
|