|
2 | 2 |
|
3 | 3 | import asyncio |
4 | 4 | import logging |
5 | | -from contextlib import AsyncExitStack, asynccontextmanager |
| 5 | +from contextlib import asynccontextmanager |
6 | 6 | from typing import AsyncGenerator |
7 | 7 |
|
8 | 8 | import redis.asyncio as redis |
|
15 | 15 | from app.core.startup import initialize_rate_limits |
16 | 16 | from app.core.tracing import init_tracing |
17 | 17 | from app.db.docs import ALL_DOCUMENTS |
18 | | -from app.events.event_store_consumer import EventStoreConsumer |
19 | 18 | from app.events.schema.schema_registry import SchemaRegistryManager, initialize_event_schemas |
20 | 19 | from app.services.notification_service import NotificationService |
21 | 20 | from app.services.sse.kafka_redis_bridge import SSEKafkaRedisBridge |
@@ -76,43 +75,23 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: |
76 | 75 | extra={"testing": settings.TESTING, "enable_tracing": settings.ENABLE_TRACING}, |
77 | 76 | ) |
78 | 77 |
|
79 | | - # Phase 1: Resolve all DI dependencies in parallel |
80 | | - ( |
81 | | - schema_registry, |
82 | | - database, |
83 | | - redis_client, |
84 | | - rate_limit_metrics, |
85 | | - sse_bridge, |
86 | | - event_store_consumer, |
87 | | - notification_service, |
88 | | - ) = await asyncio.gather( |
| 78 | + # Resolve DI dependencies in parallel (fail fast on config issues) |
| 79 | + schema_registry, database, redis_client, rate_limit_metrics, _, _ = await asyncio.gather( |
89 | 80 | container.get(SchemaRegistryManager), |
90 | 81 | container.get(Database), |
91 | 82 | container.get(redis.Redis), |
92 | 83 | container.get(RateLimitMetrics), |
93 | 84 | container.get(SSEKafkaRedisBridge), |
94 | | - container.get(EventStoreConsumer), |
95 | 85 | container.get(NotificationService), |
96 | 86 | ) |
97 | 87 |
|
98 | | - # Phase 2: Initialize infrastructure in parallel (independent subsystems) |
| 88 | + # Initialize infrastructure in parallel |
99 | 89 | await asyncio.gather( |
100 | 90 | initialize_event_schemas(schema_registry), |
101 | 91 | init_beanie(database=database, document_models=ALL_DOCUMENTS), |
102 | 92 | initialize_rate_limits(redis_client, settings, logger, rate_limit_metrics), |
103 | 93 | ) |
104 | 94 | logger.info("Infrastructure initialized (schemas, beanie, rate limits)") |
105 | 95 |
|
106 | | - # Phase 3: Start Kafka consumers in parallel (providers already started them via async with, |
107 | | - # but __aenter__ is idempotent so this is safe and explicit) |
108 | | - async with AsyncExitStack() as stack: |
109 | | - stack.push_async_callback(sse_bridge.aclose) |
110 | | - stack.push_async_callback(event_store_consumer.aclose) |
111 | | - stack.push_async_callback(notification_service.aclose) |
112 | | - await asyncio.gather( |
113 | | - sse_bridge.__aenter__(), |
114 | | - event_store_consumer.__aenter__(), |
115 | | - notification_service.__aenter__(), |
116 | | - ) |
117 | | - logger.info("SSE bridge, EventStoreConsumer, and NotificationService started") |
118 | | - yield |
| 96 | + yield |
| 97 | + # Container close handles all cleanup automatically |
0 commit comments