forked from juspay/clairvoyance
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun.py
More file actions
73 lines (61 loc) · 2.69 KB
/
run.py
File metadata and controls
73 lines (61 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# STEP 1: Load environment variables VERY FIRST - before any other imports
from dotenv import load_dotenv
load_dotenv()
# STEP 2: Now safe to import everything else
import asyncio
import uvicorn
# STEP 3: Now safe to import config and logger
from app.core.config.static import HOST, PORT, UVICORN_LOG_LEVEL, UVICORN_RELOAD
from app.core.logger import logger
from app.services.live_config.store import initialize_feature_flags
from app.services.redis import (
close_redis_connections,
get_redis_service,
is_redis_configured,
)
async def initialize_devcycle():
"""Initialize DevCycle and populate Redis before uvicorn starts.
This ensures all worker processes and subprocesses can read flags from Redis
without needing to call DevCycle API themselves.
"""
try:
if is_redis_configured():
# Initialize Redis connection
redis_service = await get_redis_service()
await redis_service.get_client() # Initialize the client
logger.info("Parent process: Redis connection established")
# Initialize DevCycle and populate Redis
await initialize_feature_flags()
logger.info(
"Parent process: DevCycle feature flags initialized and stored in Redis"
)
# Close Redis connection (workers will create their own)
await close_redis_connections()
logger.info(
"Parent process: Redis connection closed (workers will create new connections)"
)
else:
logger.warning(
"Parent process: Redis not configured - DevCycle flags will use environment variables only"
)
except Exception as e:
logger.error(f"Parent process: Failed to initialize DevCycle: {e}")
logger.warning("Parent process: Continuing with environment variable fallback")
if __name__ == "__main__":
# STEP 4: Initialize DevCycle in parent process before starting uvicorn
logger.info("Parent process: Initializing DevCycle before starting workers...")
asyncio.run(initialize_devcycle())
# STEP 5: Start uvicorn server (will spawn worker processes)
logger.info(f"Starting Uvicorn server on {HOST}:{PORT}")
logger.info(f"Reload enabled: {UVICORN_RELOAD}")
logger.info(f"Log level: {UVICORN_LOG_LEVEL}")
logger.info("Running the main application.")
uvicorn.run(
"app.main:app", # Path to the FastAPI app object in app/main.py
host=HOST,
port=PORT,
reload=UVICORN_RELOAD,
log_level=UVICORN_LOG_LEVEL,
log_config=None, # Disable Uvicorn's default logging config
access_log=True, # Keep access logs but route through our interceptor
)