refactor(db)!: finalize pooled WNDB v2 migration
This commit is contained in:
@@ -11,6 +11,7 @@ from psycopg_pool import ConnectionPool
|
||||
from app.core.config import settings
|
||||
from app.infra.db.project_routing import get_project_pgconn_string
|
||||
|
||||
_check_connection = ConnectionPool.check_connection
|
||||
_pools: OrderedDict[str, ConnectionPool] = OrderedDict()
|
||||
_pool_conninfo: dict[str, str] = {}
|
||||
_pool_borrows: dict[str, int] = {}
|
||||
@@ -21,6 +22,10 @@ _active_project_connection: ContextVar[tuple[str, Connection] | None] = ContextV
|
||||
"wndb_active_project_connection",
|
||||
default=None,
|
||||
)
|
||||
_active_model_mutation_locks: ContextVar[frozenset[str]] = ContextVar(
|
||||
"wndb_active_model_mutation_locks",
|
||||
default=frozenset(),
|
||||
)
|
||||
|
||||
|
||||
def _close_pool(pool: ConnectionPool) -> None:
|
||||
@@ -78,6 +83,7 @@ def get_project_pool(name: str) -> ConnectionPool:
|
||||
min_size=settings.PROJECT_PG_POOL_MIN_SIZE,
|
||||
max_size=settings.PROJECT_PG_POOL_SIZE + settings.PROJECT_PG_MAX_OVERFLOW,
|
||||
kwargs={"autocommit": True, "row_factory": dict_row},
|
||||
check=_check_connection,
|
||||
open=True,
|
||||
)
|
||||
_pools[name] = pool
|
||||
@@ -140,6 +146,7 @@ def get_admin_pool() -> ConnectionPool:
|
||||
min_size=settings.PROJECT_PG_POOL_MIN_SIZE,
|
||||
max_size=settings.PROJECT_PG_POOL_SIZE,
|
||||
kwargs={"autocommit": True, "row_factory": dict_row},
|
||||
check=_check_connection,
|
||||
open=True,
|
||||
)
|
||||
_admin_pools[conninfo] = pool
|
||||
@@ -192,10 +199,12 @@ def project_transaction(name: str) -> Iterator[Connection]:
|
||||
try:
|
||||
with pool.connection() as conn:
|
||||
token = _active_project_connection.set((name, conn))
|
||||
lock_token = _active_model_mutation_locks.set(frozenset())
|
||||
try:
|
||||
with conn.transaction():
|
||||
yield conn
|
||||
finally:
|
||||
_active_model_mutation_locks.reset(lock_token)
|
||||
_active_project_connection.reset(token)
|
||||
finally:
|
||||
with _registry_lock:
|
||||
@@ -208,6 +217,17 @@ def is_project_transaction_active(name: str) -> bool:
|
||||
return active is not None and active[0] == name
|
||||
|
||||
|
||||
def is_model_mutation_lock_active(name: str) -> bool:
|
||||
"""Return whether the current project transaction already owns its model lock."""
|
||||
return name in _active_model_mutation_locks.get()
|
||||
|
||||
|
||||
def mark_model_mutation_lock_active(name: str) -> None:
|
||||
"""Record a transaction-scoped advisory lock to avoid duplicate round trips."""
|
||||
locks = _active_model_mutation_locks.get()
|
||||
_active_model_mutation_locks.set(locks | {name})
|
||||
|
||||
|
||||
@contextmanager
|
||||
def admin_connection() -> Iterator[Connection]:
|
||||
"""Borrow a PostgreSQL administration connection from its pool."""
|
||||
|
||||
Reference in New Issue
Block a user