Chat-Service / app /db /postgres.py
ArabicNewsAnalyzer's picture
Update app/db/postgres.py
be24846 verified
Raw
History Blame Contribute Delete
1.84 kB
from __future__ import annotations
from contextlib import asynccontextmanager
from psycopg_pool import AsyncConnectionPool
from app.config import get_settings
_pool: AsyncConnectionPool | None = None
def get_pool() -> AsyncConnectionPool:
global _pool
if _pool is None:
settings = get_settings()
_pool = AsyncConnectionPool(
conninfo=settings.postgres_readonly_url,
min_size=1,
max_size=10,
open=False,
# --- ADDED TO FIX CROSS-CLOUD SSL DROPS ---
max_idle=30.0, # Recycle connections that sit silent for over 30s
check=AsyncConnectionPool.check_connection, # Test the connection health before handing it to your tool
kwargs={
"keepalives": 1, # Turn on TCP Keepalives
"keepalives_idle": 30, # Ping Railway every 30 seconds of silence
"keepalives_interval": 10, # If a ping fails, retry every 10 seconds
"keepalives_count": 5, # Drop the socket if 5 pings fail in a row
},
)
return _pool
async def open_pool() -> None:
"""Call on app startup."""
pool = get_pool()
if pool.closed:
await pool.open(wait=True)
async def close_pool() -> None:
"""Call on app shutdown."""
global _pool
if _pool is not None and not _pool.closed:
await _pool.close()
_pool = None
@asynccontextmanager
async def get_readonly_connection():
"""
Yields a connection with an extra read-only guard set at the
session level, on top of the chat_ro_user DB role.
"""
pool = get_pool()
async with pool.connection() as conn:
await conn.execute("SET default_transaction_read_only = on")
yield conn