Refactor database connection handling in API endpoints
- Removed direct pool checks and replaced them with a centralized database initialization method in `init_db`. - Updated API endpoints in `admin.py`, `collection.py`, `pins.py`, and `watched.py` to ensure the database connection pool is initialized before usage. - Enhanced error handling to raise HTTP exceptions if the database is unavailable. - Improved the `init_db` function in `database.py` to prevent multiple simultaneous initializations using an asyncio lock.
This commit is contained in:
@@ -4,28 +4,52 @@ from psycopg_pool import AsyncConnectionPool
|
||||
from app.core.config import settings
|
||||
from typing import Optional
|
||||
import logging
|
||||
import asyncio
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Connection pool
|
||||
pool: Optional[AsyncConnectionPool] = None
|
||||
_init_lock = asyncio.Lock()
|
||||
_initializing = False
|
||||
|
||||
|
||||
async def init_db():
|
||||
"""Initialize database connection pool"""
|
||||
global pool
|
||||
try:
|
||||
pool = AsyncConnectionPool(
|
||||
conninfo=settings.database_url,
|
||||
min_size=1,
|
||||
max_size=10,
|
||||
open=False,
|
||||
)
|
||||
await pool.open()
|
||||
logger.info("Database connection pool initialized")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to initialize database pool: {e}")
|
||||
raise
|
||||
global pool, _initializing
|
||||
|
||||
# If already initialized, return
|
||||
if pool is not None:
|
||||
return
|
||||
|
||||
# Use lock to prevent multiple simultaneous initializations
|
||||
async with _init_lock:
|
||||
# Double-check after acquiring lock
|
||||
if pool is not None:
|
||||
return
|
||||
|
||||
if _initializing:
|
||||
# Wait for other initialization to complete
|
||||
while _initializing:
|
||||
await asyncio.sleep(0.1)
|
||||
return
|
||||
|
||||
_initializing = True
|
||||
try:
|
||||
pool = AsyncConnectionPool(
|
||||
conninfo=settings.database_url,
|
||||
min_size=1,
|
||||
max_size=10,
|
||||
open=False,
|
||||
)
|
||||
await pool.open()
|
||||
logger.info("Database connection pool initialized")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to initialize database pool: {e}")
|
||||
pool = None
|
||||
raise
|
||||
finally:
|
||||
_initializing = False
|
||||
|
||||
|
||||
async def close_db():
|
||||
|
||||
Reference in New Issue
Block a user