feat: implement graceful shutdown with SIGINT/SIGTERM support
- Add WebSocket shutdown() with client notification and graceful close - Enhance download service stop() with pending state persistence - Expand FastAPI lifespan shutdown with proper cleanup sequence - Add SQLite WAL checkpoint before database close - Update stop_server.sh to use SIGTERM with timeout fallback - Configure uvicorn timeout_graceful_shutdown=30s - Update ARCHITECTURE.md with shutdown documentation
This commit is contained in:
@@ -150,11 +150,29 @@ async def init_db() -> None:
|
||||
async def close_db() -> None:
|
||||
"""Close database connections and cleanup resources.
|
||||
|
||||
Performs a WAL checkpoint for SQLite databases to ensure all
|
||||
pending writes are flushed to the main database file before
|
||||
closing connections. This prevents database corruption during
|
||||
shutdown.
|
||||
|
||||
Should be called during application shutdown.
|
||||
"""
|
||||
global _engine, _sync_engine, _session_factory, _sync_session_factory
|
||||
|
||||
try:
|
||||
# For SQLite: checkpoint WAL to ensure all writes are flushed
|
||||
if _sync_engine and "sqlite" in str(_sync_engine.url):
|
||||
logger.info("Running SQLite WAL checkpoint before shutdown...")
|
||||
try:
|
||||
from sqlalchemy import text
|
||||
with _sync_engine.connect() as conn:
|
||||
# TRUNCATE mode: checkpoint and truncate WAL file
|
||||
conn.execute(text("PRAGMA wal_checkpoint(TRUNCATE)"))
|
||||
conn.commit()
|
||||
logger.info("SQLite WAL checkpoint completed")
|
||||
except Exception as e:
|
||||
logger.warning(f"WAL checkpoint failed (non-critical): {e}")
|
||||
|
||||
if _engine:
|
||||
logger.info("Closing async database engine...")
|
||||
await _engine.dispose()
|
||||
|
||||
Reference in New Issue
Block a user