Update app.py
Browse files
app.py
CHANGED
|
@@ -29,6 +29,22 @@ print(f"[BOOT] POINTER_URL={POINTER_URL or '(unset)'}")
|
|
| 29 |
print(f"[BOOT] FALLBACK_BASE={FALLBACK_BASE}")
|
| 30 |
_backend_url_cache = {"url": None, "ts": 0.0}
|
| 31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
def get_backend_base() -> str:
|
| 33 |
try:
|
| 34 |
if POINTER_URL:
|
|
@@ -496,6 +512,12 @@ def warmup_status():
|
|
| 496 |
|
| 497 |
data = deepcopy(warmup_state)
|
| 498 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 499 |
# --- AJOUT : état du cache actuel ---
|
| 500 |
cached = _list_cached_repos()
|
| 501 |
data["audit_count"] = len(cached)
|
|
@@ -893,6 +915,11 @@ const warmupPopup = document.getElementById('warmupPopup');
|
|
| 893 |
const warmupPopupStatus = document.getElementById('warmupPopupStatus');
|
| 894 |
const warmupProgressFill = document.getElementById('warmup-progress-fill');
|
| 895 |
const warmupLogs = document.getElementById('warmup-logs');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 896 |
const warmupCloseBtn = document.getElementById('warmupCloseBtn');
|
| 897 |
|
| 898 |
// Helpers popup
|
|
@@ -930,8 +957,17 @@ let warmupTimer = null;
|
|
| 930 |
async function refreshWarmupUI(){
|
| 931 |
try{
|
| 932 |
const r = await fetch('/warmup/status');
|
| 933 |
-
|
| 934 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 935 |
const pct = Math.max(0, Math.min(100, parseInt(s.percent||0,10)));
|
| 936 |
const running = !!s.running;
|
| 937 |
|
|
@@ -942,13 +978,13 @@ async function refreshWarmupUI(){
|
|
| 942 |
|
| 943 |
|
| 944 |
const idx = (s.idx ?? 0) + 1;
|
| 945 |
-
|
| 946 |
} else {
|
| 947 |
const nCache = Number.isFinite(s.audit_count)
|
| 948 |
? s.audit_count
|
| 949 |
: (Array.isArray(s.audit_cached) ? s.audit_cached.length : 0);
|
| 950 |
if (nCache > 0) {
|
| 951 |
-
|
| 952 |
} else {
|
| 953 |
warmupStatusEl.textContent = `Prêt (aucun run)`;
|
| 954 |
}
|
|
@@ -966,6 +1002,8 @@ async function refreshWarmupUI(){
|
|
| 966 |
// Préambule construit dynamiquement à partir de /warmup/status
|
| 967 |
let prefaceNow = '';
|
| 968 |
if (Array.isArray(s.audit_cached)) {
|
|
|
|
|
|
|
| 969 |
const n = Number.isFinite(s.audit_count) ? s.audit_count : s.audit_cached.length;
|
| 970 |
prefaceNow =
|
| 971 |
'Déjà en cache (' + n + '):\n' +
|
|
|
|
| 29 |
print(f"[BOOT] FALLBACK_BASE={FALLBACK_BASE}")
|
| 30 |
_backend_url_cache = {"url": None, "ts": 0.0}
|
| 31 |
|
| 32 |
+
|
| 33 |
+
# --- Instance ID (utile si plusieurs répliques derrière un proxy) -------------
|
| 34 |
+
INSTANCE_ID = os.getenv("INSTANCE_ID", uuid.uuid4().hex[:6])
|
| 35 |
+
|
| 36 |
+
@app.middleware("http")
|
| 37 |
+
async def inject_instance_id_header(request: Request, call_next):
|
| 38 |
+
resp = await call_next(request)
|
| 39 |
+
try:
|
| 40 |
+
resp.headers["x-instance-id"] = INSTANCE_ID
|
| 41 |
+
except Exception:
|
| 42 |
+
pass
|
| 43 |
+
return resp
|
| 44 |
+
# ------------------------------------------------------------------------------
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
|
| 48 |
def get_backend_base() -> str:
|
| 49 |
try:
|
| 50 |
if POINTER_URL:
|
|
|
|
| 512 |
|
| 513 |
data = deepcopy(warmup_state)
|
| 514 |
|
| 515 |
+
|
| 516 |
+
|
| 517 |
+
# Identifiant d'instance pour aider à diagnostiquer les bascules de réplique
|
| 518 |
+
data["instance_id"] = INSTANCE_ID
|
| 519 |
+
|
| 520 |
+
|
| 521 |
# --- AJOUT : état du cache actuel ---
|
| 522 |
cached = _list_cached_repos()
|
| 523 |
data["audit_count"] = len(cached)
|
|
|
|
| 915 |
const warmupPopupStatus = document.getElementById('warmupPopupStatus');
|
| 916 |
const warmupProgressFill = document.getElementById('warmup-progress-fill');
|
| 917 |
const warmupLogs = document.getElementById('warmup-logs');
|
| 918 |
+
|
| 919 |
+
// Mémorise la dernière instance vue pour détecter les bascules
|
| 920 |
+
window._lastInstanceId = null;
|
| 921 |
+
|
| 922 |
+
|
| 923 |
const warmupCloseBtn = document.getElementById('warmupCloseBtn');
|
| 924 |
|
| 925 |
// Helpers popup
|
|
|
|
| 957 |
async function refreshWarmupUI(){
|
| 958 |
try{
|
| 959 |
const r = await fetch('/warmup/status');
|
| 960 |
+
|
| 961 |
+
|
| 962 |
+
|
| 963 |
+
// Instance courante (ajout backend)
|
| 964 |
+
const instanceId = s.instance_id || 'n/a';
|
| 965 |
+
if (window._lastInstanceId && window._lastInstanceId !== instanceId) {
|
| 966 |
+
showToast(`Bascule d'instance détectée : ${window._lastInstanceId} → ${instanceId}`);
|
| 967 |
+
}
|
| 968 |
+
window._lastInstanceId = instanceId;
|
| 969 |
+
|
| 970 |
+
|
| 971 |
const pct = Math.max(0, Math.min(100, parseInt(s.percent||0,10)));
|
| 972 |
const running = !!s.running;
|
| 973 |
|
|
|
|
| 978 |
|
| 979 |
|
| 980 |
const idx = (s.idx ?? 0) + 1;
|
| 981 |
+
warmupStatusEl.textContent = `⏳ ${pct}% — ${s.current||''} (${idx}/${tot}) [inst:${instanceId}]`;
|
| 982 |
} else {
|
| 983 |
const nCache = Number.isFinite(s.audit_count)
|
| 984 |
? s.audit_count
|
| 985 |
: (Array.isArray(s.audit_cached) ? s.audit_cached.length : 0);
|
| 986 |
if (nCache > 0) {
|
| 987 |
+
warmupStatusEl.textContent = `✅ Terminé — cache local: ${nCache} (inst:${instanceId})`;
|
| 988 |
} else {
|
| 989 |
warmupStatusEl.textContent = `Prêt (aucun run)`;
|
| 990 |
}
|
|
|
|
| 1002 |
// Préambule construit dynamiquement à partir de /warmup/status
|
| 1003 |
let prefaceNow = '';
|
| 1004 |
if (Array.isArray(s.audit_cached)) {
|
| 1005 |
+
prefaceNow = `[Instance ${instanceId}]` + '\n' + prefaceNow;
|
| 1006 |
+
|
| 1007 |
const n = Number.isFinite(s.audit_count) ? s.audit_count : s.audit_cached.length;
|
| 1008 |
prefaceNow =
|
| 1009 |
'Déjà en cache (' + n + '):\n' +
|