mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-17 23:09:35 +00:00
fix: harden Railway startup — fault-tolerant lifespan + DB retry + credential cleanup
- Wrap PostHog/DLQ init in try/except so startup survives missing services - Delay self-improvement worker 30s to reduce startup load - Run init_db() for ALL database types (was SQLite-only, skipping PostgreSQL) - Add 3-attempt retry with backoff in init_db() for Railway DB startup race - Fix FastAPI deprecation: regex → pattern in intelligence.py - Remove hardcoded Ultramsg credentials from auto_pipeline.py https://claude.ai/code/session_01W1rJthWDkasijTdXCfxVHs
This commit is contained in:
parent
87d2c0d13b
commit
0723407a6d
@ -126,7 +126,7 @@ async def alert_stats(tenant_id: str):
|
|||||||
|
|
||||||
@router.get("/digest", summary="Generate Arabic alert digest")
|
@router.get("/digest", summary="Generate Arabic alert digest")
|
||||||
async def generate_digest(tenant_id: str, user_id: Optional[str] = None,
|
async def generate_digest(tenant_id: str, user_id: Optional[str] = None,
|
||||||
period: str = Query(default="daily", regex="^(daily|weekly)$")):
|
period: str = Query(default="daily", pattern="^(daily|weekly)$")):
|
||||||
return await get_alert_delivery().generate_digest(tenant_id, user_id, period)
|
return await get_alert_delivery().generate_digest(tenant_id, user_id, period)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -70,13 +70,24 @@ async def get_db():
|
|||||||
async def init_db():
|
async def init_db():
|
||||||
import app.models # noqa: F401 — register all models on Base.metadata before create_all
|
import app.models # noqa: F401 — register all models on Base.metadata before create_all
|
||||||
|
|
||||||
async with engine.begin() as conn:
|
for attempt in range(3):
|
||||||
if not IS_SQLITE:
|
try:
|
||||||
for ext in ["CREATE EXTENSION IF NOT EXISTS vector",
|
async with engine.begin() as conn:
|
||||||
"CREATE EXTENSION IF NOT EXISTS pg_trgm"]:
|
if not IS_SQLITE:
|
||||||
try:
|
for ext in ["CREATE EXTENSION IF NOT EXISTS vector",
|
||||||
await conn.execute(text(ext))
|
"CREATE EXTENSION IF NOT EXISTS pg_trgm"]:
|
||||||
except Exception:
|
try:
|
||||||
pass
|
await conn.execute(text(ext))
|
||||||
await conn.run_sync(Base.metadata.create_all)
|
except Exception:
|
||||||
print("✅ Database initialized")
|
pass
|
||||||
|
await conn.run_sync(Base.metadata.create_all)
|
||||||
|
print("✅ Database initialized")
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
if attempt < 2:
|
||||||
|
import asyncio
|
||||||
|
print(f"⚠️ DB init attempt {attempt + 1} failed: {e}, retrying in 3s...")
|
||||||
|
await asyncio.sleep(3)
|
||||||
|
else:
|
||||||
|
print(f"❌ DB init failed after 3 attempts: {e}")
|
||||||
|
raise
|
||||||
|
|||||||
@ -50,18 +50,22 @@ async def lifespan(app: FastAPI):
|
|||||||
stop_event = asyncio.Event()
|
stop_event = asyncio.Event()
|
||||||
|
|
||||||
async def _self_improvement_worker():
|
async def _self_improvement_worker():
|
||||||
|
await asyncio.sleep(30)
|
||||||
while not stop_event.is_set():
|
while not stop_event.is_set():
|
||||||
self_improvement_flow.run(
|
try:
|
||||||
tenant_id="system_tenant",
|
self_improvement_flow.run(
|
||||||
input_state={
|
tenant_id="system_tenant",
|
||||||
"signals": [],
|
input_state={
|
||||||
"bottlenecks": [],
|
"signals": [],
|
||||||
"experiments": [{"name": "always-on-ab-loop"}],
|
"bottlenecks": [],
|
||||||
"ab_results": {},
|
"experiments": [{"name": "always-on-ab-loop"}],
|
||||||
"governance_passed": True,
|
"ab_results": {},
|
||||||
"promoted": True,
|
"governance_passed": True,
|
||||||
},
|
"promoted": True,
|
||||||
)
|
},
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
await asyncio.sleep(max(60, settings.SELF_IMPROVEMENT_INTERVAL_SECONDS))
|
await asyncio.sleep(max(60, settings.SELF_IMPROVEMENT_INTERVAL_SECONDS))
|
||||||
|
|
||||||
worker_task = asyncio.create_task(_self_improvement_worker())
|
worker_task = asyncio.create_task(_self_improvement_worker())
|
||||||
@ -72,16 +76,20 @@ async def lifespan(app: FastAPI):
|
|||||||
print(f" LLM Primary: {settings.LLM_PRIMARY_PROVIDER}")
|
print(f" LLM Primary: {settings.LLM_PRIMARY_PROVIDER}")
|
||||||
print(f" LLM Fallback: {settings.LLM_FALLBACK_PROVIDER}")
|
print(f" LLM Fallback: {settings.LLM_FALLBACK_PROVIDER}")
|
||||||
|
|
||||||
# Initialize PostHog
|
try:
|
||||||
from app.services.posthog_client import get_posthog
|
from app.services.posthog_client import get_posthog
|
||||||
ph = get_posthog()
|
ph = get_posthog()
|
||||||
print(f" PostHog: {'enabled' if ph._enabled else 'disabled (no API key)'}")
|
print(f" PostHog: {'enabled' if getattr(ph, '_enabled', False) else 'disabled (no API key)'}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" PostHog: init failed ({e})")
|
||||||
|
|
||||||
# Initialize DLQ
|
try:
|
||||||
from app.services.dlq import dlq
|
from app.services.dlq import dlq # noqa: F841
|
||||||
print(" DLQ: initialized")
|
print(" DLQ: initialized")
|
||||||
if IS_SQLITE:
|
except Exception as e:
|
||||||
await init_db()
|
print(f" DLQ: init failed ({e})")
|
||||||
|
|
||||||
|
await init_db()
|
||||||
yield
|
yield
|
||||||
# Shutdown
|
# Shutdown
|
||||||
stop_event.set()
|
stop_event.set()
|
||||||
|
|||||||
@ -115,8 +115,8 @@ class WhatsAppMessenger:
|
|||||||
"""Send messages via Ultramsg API."""
|
"""Send messages via Ultramsg API."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.instance_id = os.getenv("ULTRAMSG_INSTANCE_ID", "instance168132")
|
self.instance_id = os.getenv("ULTRAMSG_INSTANCE_ID", "")
|
||||||
self.token = os.getenv("ULTRAMSG_TOKEN", "7azj2ss74wpg9jwp")
|
self.token = os.getenv("ULTRAMSG_TOKEN", "")
|
||||||
self.api_base = f"https://api.ultramsg.com/{self.instance_id}"
|
self.api_base = f"https://api.ultramsg.com/{self.instance_id}"
|
||||||
|
|
||||||
async def send_message(self, phone: str, message: str) -> Dict:
|
async def send_message(self, phone: str, message: str) -> Dict:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user