mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 05:30:46 +08:00
Add shared CLI budget/timeout with force-close, parallel port-traffic dispatch, unified shutdown, bounded audit queue, output/log caps, and /metrics probes. Co-authored-by: Cursor <cursoragent@cursor.com>
67 lines
2.1 KiB
Python
67 lines
2.1 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.orm import DeclarativeBase, sessionmaker
|
|
from sqlalchemy.pool import QueuePool
|
|
|
|
from .config import settings
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
def _engine_kwargs() -> dict[str, Any]:
|
|
url = str(settings.database_url or "")
|
|
kwargs: dict[str, Any] = {"future": True, "pool_pre_ping": True}
|
|
# SQLite (tests / local) does not use QueuePool the same way.
|
|
if url.startswith("sqlite"):
|
|
kwargs["connect_args"] = {"check_same_thread": False}
|
|
return kwargs
|
|
kwargs.update(
|
|
{
|
|
"poolclass": QueuePool,
|
|
"pool_size": max(1, int(getattr(settings, "db_pool_size", 20) or 20)),
|
|
"max_overflow": max(0, int(getattr(settings, "db_max_overflow", 20) or 20)),
|
|
"pool_recycle": max(60, int(getattr(settings, "db_pool_recycle_sec", 1800) or 1800)),
|
|
"pool_timeout": max(1, int(getattr(settings, "db_pool_timeout_sec", 30) or 30)),
|
|
}
|
|
)
|
|
return kwargs
|
|
|
|
|
|
engine = create_engine(settings.database_url, **_engine_kwargs())
|
|
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False, expire_on_commit=False)
|
|
|
|
|
|
def get_db():
|
|
db = SessionLocal()
|
|
try:
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
def db_pool_status() -> dict[str, Any]:
|
|
"""Best-effort QueuePool snapshot for readiness / metrics."""
|
|
pool = getattr(engine, "pool", None)
|
|
if pool is None:
|
|
return {"backend": "none"}
|
|
out: dict[str, Any] = {"backend": type(pool).__name__}
|
|
for key, meth in (
|
|
("size", "size"),
|
|
("checked_in", "checkedin"),
|
|
("checked_out", "checkedout"),
|
|
("overflow", "overflow"),
|
|
):
|
|
fn = getattr(pool, meth, None)
|
|
if callable(fn):
|
|
try:
|
|
out[key] = int(fn())
|
|
except Exception: # noqa: BLE001
|
|
pass
|
|
out["pool_size_cfg"] = int(getattr(settings, "db_pool_size", 20) or 20)
|
|
out["max_overflow_cfg"] = int(getattr(settings, "db_max_overflow", 20) or 20)
|
|
return out
|