fix(deploy): wait for state stores on startup
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import asyncio
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
@@ -16,6 +18,10 @@ from gapido_auth.infrastructure.rabbitmq import RabbitMqSmsPublisher
|
||||
from gapido_auth.infrastructure.redis_otp_store import RedisOtpStore
|
||||
from gapido_auth.infrastructure.sms_provider import get_sms_template
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
STARTUP_RETRY_ATTEMPTS = 30
|
||||
STARTUP_RETRY_DELAY_SECONDS = 2
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class AppContainer:
|
||||
@@ -29,15 +35,17 @@ class AppContainer:
|
||||
async def build_auth_service(settings: Settings, rabbitmq_channel: AbstractChannel) -> AppContainer:
|
||||
"""Create repositories, adapters, policies, and the AuthService use-case object."""
|
||||
|
||||
mongo_client: AsyncIOMotorClient[Any] = AsyncIOMotorClient(settings.mongo_uri)
|
||||
mongo_client: AsyncIOMotorClient[Any] = AsyncIOMotorClient(
|
||||
settings.mongo_uri,
|
||||
serverSelectionTimeoutMS=2000,
|
||||
)
|
||||
db = mongo_client[settings.mongo_db_name]
|
||||
users = MongoUserRepository(db)
|
||||
refresh_sessions = MongoRefreshSessionRepository(db)
|
||||
await users.create_indexes()
|
||||
await refresh_sessions.create_indexes()
|
||||
await users.ensure_admin_user(settings.admin_mobile)
|
||||
|
||||
redis = Redis.from_url(settings.redis_url, decode_responses=False)
|
||||
await _wait_for_state_stores(users, refresh_sessions, redis, settings.admin_mobile)
|
||||
|
||||
otp_store = RedisOtpStore(redis)
|
||||
sms_publisher = RabbitMqSmsPublisher(rabbitmq_channel)
|
||||
token_codec = JwtTokenCodec(
|
||||
@@ -62,3 +70,30 @@ async def build_auth_service(settings: Settings, rabbitmq_channel: AbstractChann
|
||||
),
|
||||
)
|
||||
return AppContainer(auth_service=auth_service, mongo_client=mongo_client, redis=redis)
|
||||
|
||||
|
||||
async def _wait_for_state_stores(
|
||||
users: MongoUserRepository,
|
||||
refresh_sessions: MongoRefreshSessionRepository,
|
||||
redis: Redis,
|
||||
admin_mobile: str,
|
||||
) -> None:
|
||||
"""Wait for MongoDB and Redis before exposing the gRPC server."""
|
||||
|
||||
for attempt in range(1, STARTUP_RETRY_ATTEMPTS + 1):
|
||||
try:
|
||||
await users.create_indexes()
|
||||
await refresh_sessions.create_indexes()
|
||||
await users.ensure_admin_user(admin_mobile)
|
||||
await redis.ping()
|
||||
return
|
||||
except Exception:
|
||||
if attempt >= STARTUP_RETRY_ATTEMPTS:
|
||||
logger.exception("State stores did not become ready during auth-service startup")
|
||||
raise
|
||||
logger.info(
|
||||
"Waiting for MongoDB/Redis before auth-service startup attempt=%s/%s",
|
||||
attempt,
|
||||
STARTUP_RETRY_ATTEMPTS,
|
||||
)
|
||||
await asyncio.sleep(STARTUP_RETRY_DELAY_SECONDS)
|
||||
|
||||
Reference in New Issue
Block a user