fix: rework lifecycle management to optimize cloud deployment (#320)

Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Paul Hernandez
2025-09-28 15:11:38 -05:00
committed by GitHub
parent 324844a670
commit ea2e93d926
3 changed files with 7 additions and 39 deletions
+5 -4
View File
@@ -22,18 +22,19 @@ from basic_memory.api.routers import (
webdav,
)
from basic_memory.config import ConfigManager
from basic_memory.services.initialization import initialize_file_sync
from basic_memory.services.initialization import initialize_file_sync, initialize_app
@asynccontextmanager
async def lifespan(app: FastAPI): # pragma: no cover
"""Lifecycle manager for the FastAPI app."""
"""Lifecycle manager for the FastAPI app. Not called in stdio mcp mode"""
app_config = ConfigManager().config
logger.info("Starting Basic Memory API")
print(f"fastapi {app_config.projects}")
# Cache database connections in app state for performance (no project reconciliation)
await initialize_app(app_config)
# Cache database connections in app state for performance
logger.info("Initializing database and caching connections...")
engine, session_maker = await db.get_or_create_db(app_config.database_path)
app.state.engine = engine
+2 -4
View File
@@ -17,6 +17,8 @@ import basic_memory.mcp.tools # noqa: F401 # pragma: no cover
# Import prompts to register them
import basic_memory.mcp.prompts # noqa: F401 # pragma: no cover
from loguru import logger
import threading
from basic_memory.services.initialization import initialize_file_sync
@app.command()
@@ -50,10 +52,6 @@ def mcp(
os.environ["BASIC_MEMORY_MCP_PROJECT"] = project_name
logger.info(f"MCP server constrained to project: {project_name}")
# Use unified thread-based sync approach for both transports
import threading
from basic_memory.services.initialization import initialize_file_sync
app_config = ConfigManager().config
def run_file_sync():
-31
View File
@@ -2,39 +2,8 @@
Basic Memory FastMCP server.
"""
import asyncio
from contextlib import asynccontextmanager
from dataclasses import dataclass
from typing import AsyncIterator, Optional, Any
from fastmcp import FastMCP
from basic_memory.config import ConfigManager
from basic_memory.services.initialization import initialize_app
@dataclass
class AppContext:
watch_task: Optional[asyncio.Task]
migration_manager: Optional[Any] = None
@asynccontextmanager
async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]: # pragma: no cover
""" """
app_config = ConfigManager().config
# Initialize on startup (now returns migration_manager)
migration_manager = await initialize_app(app_config)
try:
yield AppContext(watch_task=None, migration_manager=migration_manager)
finally:
# Cleanup on shutdown - migration tasks will be cancelled automatically
pass
# Create the shared server instance with custom Stytch auth
mcp = FastMCP(
name="Basic Memory",
lifespan=app_lifespan,
)