diff options
| author | Christian Cleberg <[email protected]> | 2026-04-11 22:56:22 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-11 22:56:22 -0500 |
| commit | 1c8d0bdd0a0a46d7400b0827aec88a787f5a04c3 (patch) | |
| tree | 516a47d260e9a1a003110dd5b20f26dffe013536 /src/srht_contrib/db.py | |
| parent | 3489797460f9f8d19d37806da3b99c6b0baf4cf0 (diff) | |
| download | hutch-stats-1c8d0bdd0a0a46d7400b0827aec88a787f5a04c3.tar.gz hutch-stats-1c8d0bdd0a0a46d7400b0827aec88a787f5a04c3.tar.bz2 hutch-stats-1c8d0bdd0a0a46d7400b0827aec88a787f5a04c3.zip | |
Reduce SQLite lock contention during actor enqueue
Diffstat (limited to 'src/srht_contrib/db.py')
| -rw-r--r-- | src/srht_contrib/db.py | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/srht_contrib/db.py b/src/srht_contrib/db.py index d96de57..7750df6 100644 --- a/src/srht_contrib/db.py +++ b/src/srht_contrib/db.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections.abc import Generator from fastapi import HTTPException, Request, status -from sqlalchemy import Engine, create_engine, text +from sqlalchemy import Engine, create_engine, event, text from sqlalchemy.pool import StaticPool from sqlalchemy.orm import Session, declarative_base, sessionmaker @@ -13,11 +13,28 @@ Base = declarative_base() def make_engine(settings: Settings) -> Engine: - connect_args = {"check_same_thread": False} if settings.database_url.startswith("sqlite") else {} + connect_args = {} + if settings.database_url.startswith("sqlite"): + connect_args = { + "check_same_thread": False, + "timeout": settings.sqlite_busy_timeout_seconds, + } engine_kwargs = {"future": True, "connect_args": connect_args} if settings.database_url in {"sqlite://", "sqlite:///:memory:"}: engine_kwargs["poolclass"] = StaticPool - return create_engine(settings.database_url, **engine_kwargs) + engine = create_engine(settings.database_url, **engine_kwargs) + + if settings.database_url.startswith("sqlite"): + @event.listens_for(engine, "connect") + def _configure_sqlite(dbapi_connection, connection_record) -> None: # type: ignore[unused-ignore] + cursor = dbapi_connection.cursor() + cursor.execute(f"PRAGMA busy_timeout = {int(settings.sqlite_busy_timeout_seconds * 1000)}") + if settings.database_url not in {"sqlite://", "sqlite:///:memory:"}: + cursor.execute("PRAGMA journal_mode = WAL") + cursor.execute("PRAGMA synchronous = NORMAL") + cursor.close() + + return engine def make_session_factory(settings: Settings) -> sessionmaker[Session]: |
