2323 fastapi_users ,
2424 websocket_auth ,
2525)
26+ from advanced_omi_backend .client_manager import get_client_manager
27+ from advanced_omi_backend .middleware .app_middleware import setup_middleware
28+ from advanced_omi_backend .routers .api_router import router as api_router
29+ from advanced_omi_backend .routers .modules .health_routes import router as health_router
30+ from advanced_omi_backend .routers .modules .websocket_routes import (
31+ router as websocket_router ,
32+ )
33+ from advanced_omi_backend .services .audio_service import get_audio_stream_service
34+ from advanced_omi_backend .services .memory import (
35+ get_memory_service ,
36+ shutdown_memory_service ,
37+ )
38+ from advanced_omi_backend .task_manager import get_task_manager , init_task_manager
2639from advanced_omi_backend .users import (
2740 User ,
2841 UserRead ,
2942 UserUpdate ,
3043 register_client_to_user ,
3144)
32- from advanced_omi_backend .client_manager import get_client_manager
33- from advanced_omi_backend .services .memory import get_memory_service , shutdown_memory_service
34- from advanced_omi_backend .middleware .app_middleware import setup_middleware
35- from advanced_omi_backend .routers .api_router import router as api_router
36- from advanced_omi_backend .routers .modules .health_routes import router as health_router
37- from advanced_omi_backend .routers .modules .websocket_routes import router as websocket_router
38- from advanced_omi_backend .services .audio_service import get_audio_stream_service
39- from advanced_omi_backend .task_manager import init_task_manager , get_task_manager
4045
4146logger = logging .getLogger (__name__ )
4247application_logger = logging .getLogger ("audio_processing" )
@@ -51,7 +56,10 @@ async def initialize_openmemory_user() -> None:
5156 - Creates a test memory and deletes it to trigger user creation
5257 - Logs success or warning if OpenMemory is not reachable
5358 """
54- from advanced_omi_backend .services .memory .config import build_memory_config_from_env , MemoryProvider
59+ from advanced_omi_backend .services .memory .config import (
60+ MemoryProvider ,
61+ build_memory_config_from_env ,
62+ )
5563
5664 memory_provider_config = build_memory_config_from_env ()
5765
@@ -99,11 +107,12 @@ async def lifespan(app: FastAPI):
99107 # Initialize Beanie for all document models
100108 try :
101109 from beanie import init_beanie
102- from advanced_omi_backend .models .conversation import Conversation
110+
111+ from advanced_omi_backend .models .annotation import Annotation
103112 from advanced_omi_backend .models .audio_chunk import AudioChunkDocument
113+ from advanced_omi_backend .models .conversation import Conversation
104114 from advanced_omi_backend .models .user import User
105115 from advanced_omi_backend .models .waveform import WaveformData
106- from advanced_omi_backend .models .annotation import Annotation
107116
108117 await init_beanie (
109118 database = config .db ,
@@ -139,6 +148,27 @@ async def lifespan(app: FastAPI):
139148 application_logger .error (f"Failed to connect to Redis for RQ: { e } " )
140149 application_logger .warning ("RQ queue system will not be available - check Redis connection" )
141150
151+ # Initialize BackgroundTaskManager (must happen before any code path uses it)
152+ try :
153+ task_manager = init_task_manager ()
154+ await task_manager .start ()
155+ application_logger .info ("BackgroundTaskManager initialized and started" )
156+ except Exception as e :
157+ application_logger .error (f"Failed to initialize task manager: { e } " )
158+ raise # Task manager is essential
159+
160+ # Initialize ClientManager eagerly (prevents lazy race on first WebSocket connect)
161+ get_client_manager ()
162+ application_logger .info ("ClientManager initialized" )
163+
164+ # Initialize LLM client eagerly (catch config errors at startup, not on first request)
165+ try :
166+ from advanced_omi_backend .llm_client import get_llm_client
167+ get_llm_client ()
168+ application_logger .info ("LLM client initialized from config.yml" )
169+ except Exception as e :
170+ application_logger .warning (f"LLM client initialization deferred: { e } " )
171+
142172 # Initialize audio stream service for Redis Streams
143173 try :
144174 audio_service = get_audio_stream_service ()
@@ -161,7 +191,9 @@ async def lifespan(app: FastAPI):
161191 application_logger .info ("✅ Redis client for audio streaming producer initialized" )
162192
163193 # Initialize ClientManager Redis for cross-container client→user mapping
164- from advanced_omi_backend .client_manager import initialize_redis_for_client_manager
194+ from advanced_omi_backend .client_manager import (
195+ initialize_redis_for_client_manager ,
196+ )
165197 initialize_redis_for_client_manager (config .redis_url )
166198
167199 except Exception as e :
@@ -180,7 +212,10 @@ async def lifespan(app: FastAPI):
180212
181213 # Initialize plugins using plugin service
182214 try :
183- from advanced_omi_backend .services .plugin_service import init_plugin_router , set_plugin_router
215+ from advanced_omi_backend .services .plugin_service import (
216+ init_plugin_router ,
217+ set_plugin_router ,
218+ )
184219
185220 plugin_router = init_plugin_router ()
186221
@@ -221,11 +256,23 @@ async def lifespan(app: FastAPI):
221256 client_manager = get_client_manager ()
222257 for client_id in client_manager .get_all_client_ids ():
223258 try :
224- from advanced_omi_backend .controllers .websocket_controller import cleanup_client_state
259+ from advanced_omi_backend .controllers .websocket_controller import (
260+ cleanup_client_state ,
261+ )
225262 await cleanup_client_state (client_id )
226263 except Exception as e :
227264 application_logger .error (f"Error cleaning up client { client_id } : { e } " )
228265
266+ # Shutdown BackgroundTaskManager
267+ try :
268+ task_mgr = get_task_manager ()
269+ await task_mgr .shutdown ()
270+ application_logger .info ("BackgroundTaskManager shut down" )
271+ except RuntimeError :
272+ pass # Never initialized
273+ except Exception as e :
274+ application_logger .error (f"Error shutting down task manager: { e } " )
275+
229276 # RQ workers shut down automatically when process ends
230277 # No special cleanup needed for Redis connections
231278
@@ -250,7 +297,9 @@ async def lifespan(app: FastAPI):
250297
251298 # Shutdown plugins
252299 try :
253- from advanced_omi_backend .services .plugin_service import cleanup_plugin_router
300+ from advanced_omi_backend .services .plugin_service import (
301+ cleanup_plugin_router ,
302+ )
254303 await cleanup_plugin_router ()
255304 application_logger .info ("Plugins shut down" )
256305 except Exception as e :
0 commit comments