presenton/electron/servers/fastapi/api/lifespan.py
voidborne-d f8156df6f5 fix: configure SQLAlchemy connection pool and dispose engines on shutdown
- Add configurable pool settings via environment variables:
  DB_POOL_SIZE, DB_MAX_OVERFLOW, DB_POOL_TIMEOUT, DB_POOL_RECYCLE,
  DB_POOL_PRE_PING (defaults: 5, 10, 30s, 1800s, true)
- Enable pool_pre_ping by default to detect and recycle stale connections
- Add dispose_engines() called during FastAPI lifespan shutdown to
  release all connections back to the database
- Skip pool configuration for SQLite (uses file-lock, not connection pools)
- Apply changes to both servers/ and electron/ FastAPI instances

Fixes #453 (stale connections exhausting pool)
Fixes #454 (missing pool configuration)
2026-03-20 06:08:54 +00:00

28 lines
986 B
Python

from contextlib import asynccontextmanager
import os
from fastapi import FastAPI
from migrations import migrate_database_on_startup
from services.database import create_db_and_tables, dispose_engines
from utils.get_env import get_app_data_directory_env
from utils.model_availability import (
check_llm_and_image_provider_api_or_model_availability,
)
@asynccontextmanager
async def app_lifespan(_: FastAPI):
"""
Lifespan context manager for FastAPI application.
Initializes the application data directory, runs Alembic migrations when
MIGRATE_DATABASE_ON_STARTUP=true, creates any missing tables, and checks
LLM model availability.
"""
os.makedirs(get_app_data_directory_env(), exist_ok=True)
await migrate_database_on_startup()
await create_db_and_tables()
await check_llm_and_image_provider_api_or_model_availability()
yield
# Shutdown: release all database connections to prevent stale/leaked pools.
await dispose_engines()