A collections page fires 100+ concurrent poster requests. Both image proxies (/image and /person-image) authenticated via current_user + Depends(get_db), holding a pooled DB connection for the whole request — including the slow Plex/ CDN fetch. Under the burst, the 15-connection pool was exhausted → QueuePool checkout timeouts → 502s → slow, partially-loaded grids on prod. Fix: authenticate these two high-fan-out endpoints with a signed-session check (no DB user-load), serve disk-cache hits with zero DB access, and on a cold miss open a short session only to resolve the image key + Plex config, releasing it BEFORE the fetch (image_bytes uses no DB). Also raise the pool (20 + 30 overflow) as headroom above the sync-endpoint threadpool.
32 lines
866 B
Python
32 lines
866 B
Python
from collections.abc import Iterator
|
|
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker
|
|
|
|
from app.config import settings
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
# Pool sized above the sync-endpoint threadpool (~40) so a burst of short DB sessions can't starve on
|
|
# checkout. The image proxies deliberately DON'T hold a connection during their slow external fetch
|
|
# (see routes/plex.py), so this headroom is only for the many brief sessions, not long ones.
|
|
engine = create_engine(
|
|
settings.database_url,
|
|
pool_pre_ping=True,
|
|
pool_size=20,
|
|
max_overflow=30,
|
|
pool_timeout=30,
|
|
future=True,
|
|
)
|
|
SessionLocal = sessionmaker(bind=engine, autoflush=False, expire_on_commit=False)
|
|
|
|
|
|
def get_db() -> Iterator[Session]:
|
|
db = SessionLocal()
|
|
try:
|
|
yield db
|
|
finally:
|
|
db.close()
|