Skip to content

Commit b3c738c

Browse files
committed
feat: High availability backend URL failover
1 parent 9c45c81 commit b3c738c

File tree

1 file changed

+30
-5
lines changed

1 file changed

+30
-5
lines changed

frontend/utils/api.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,36 @@
66
import extra_streamlit_components as stx
77
from datetime import datetime, timedelta
88

9-
# Backend URL
10-
try:
11-
BACKEND_URL = os.getenv("BACKEND_URL") or st.secrets.get("BACKEND_URL") or "http://127.0.0.1:8000"
12-
except FileNotFoundError:
13-
BACKEND_URL = os.getenv("BACKEND_URL", "http://127.0.0.1:8000")
9+
# --- High-Availability Backend Resolution ---
10+
@st.cache_data(ttl=300) # Cache the active URL for 5 minutes
11+
def resolve_backend_url():
12+
urls_str = None
13+
try:
14+
urls_str = os.getenv("BACKEND_URLS") or st.secrets.get("BACKEND_URLS")
15+
except FileNotFoundError:
16+
urls_str = os.getenv("BACKEND_URLS")
17+
18+
if urls_str:
19+
urls = [u.strip() for u in urls_str.split(',') if u.strip()]
20+
# Fast failover ping
21+
for url in urls:
22+
try:
23+
# Short timeout so we don't block user for 50s per asleep instance
24+
if requests.get(f"{url}/healthz", timeout=2.5).status_code == 200:
25+
return url
26+
except requests.exceptions.RequestException:
27+
pass
28+
# All dead or asleep? Pick the primary one and let it wake naturally
29+
if urls:
30+
return urls[0]
31+
32+
# Fallback to legacy single URL
33+
try:
34+
return os.getenv("BACKEND_URL") or st.secrets.get("BACKEND_URL") or "http://127.0.0.1:8000"
35+
except FileNotFoundError:
36+
return os.getenv("BACKEND_URL", "http://127.0.0.1:8000")
37+
38+
BACKEND_URL = resolve_backend_url()
1439

1540
def get_backend_url(): return BACKEND_URL
1641

0 commit comments

Comments
 (0)