Files
lovdata-chat/session-manager/app.py
Torbjørn Lindahl 69d18cc494 fix: session stability improvements
- Fix docker client initialization bug in app.py (context manager was closing client)
- Add restart_session() method to preserve session IDs during container restarts
- Add 60-second startup grace period before health checking new sessions
- Fix _stop_container and _get_container_info to use docker_service API consistently
- Disable mDNS in Dockerfile to prevent Bonjour service name conflicts
- Remove old container before restart to free port bindings
2026-02-04 19:10:03 +01:00

93 lines
2.8 KiB
Python

import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI
from config import USE_ASYNC_DOCKER, USE_DATABASE_STORAGE
from session_manager import session_manager
from http_pool import init_http_pool, shutdown_http_pool
from database import init_database, shutdown_database, run_migrations
from container_health import (
start_container_health_monitoring,
stop_container_health_monitoring,
)
from logging_config import get_logger, init_logging
from routes import sessions_router, auth_router, health_router, proxy_router
init_logging()
logger = get_logger(__name__)
_use_database_storage = USE_DATABASE_STORAGE
@asynccontextmanager
async def lifespan(app: FastAPI):
global _use_database_storage
logger.info("Starting Session Management Service")
await init_http_pool()
if _use_database_storage:
try:
await init_database()
await run_migrations()
await session_manager._load_sessions_from_database()
logger.info("Database initialized and sessions loaded")
except Exception as e:
logger.error("Database initialization failed", extra={"error": str(e)})
if _use_database_storage:
logger.warning("Falling back to JSON file storage")
_use_database_storage = False
session_manager._load_sessions_from_file()
try:
# Use the session manager's docker_service for health monitoring
# This ensures the docker client stays alive for the lifetime of the application
docker_client = session_manager.docker_service
await start_container_health_monitoring(session_manager, docker_client)
logger.info("Container health monitoring started")
except Exception as e:
logger.error(
"Failed to start container health monitoring", extra={"error": str(e)}
)
async def cleanup_task():
while True:
await session_manager.cleanup_expired_sessions()
await asyncio.sleep(300)
cleanup_coro = asyncio.create_task(cleanup_task())
yield
logger.info("Shutting down Session Management Service")
cleanup_coro.cancel()
await shutdown_http_pool()
try:
await stop_container_health_monitoring()
logger.info("Container health monitoring stopped")
except Exception as e:
logger.error(
"Error stopping container health monitoring", extra={"error": str(e)}
)
if _use_database_storage:
await shutdown_database()
app = FastAPI(
title="Lovdata Chat Session Manager",
description="Manages isolated OpenCode containers for Norwegian legal research sessions",
version="1.0.0",
lifespan=lifespan,
)
app.include_router(sessions_router)
app.include_router(auth_router)
app.include_router(health_router)
app.include_router(proxy_router)