Update app.py
Browse files
app.py
CHANGED
@@ -1104,6 +1104,9 @@ const warmupSelectCopyBtn = document.getElementById('warmupSelectCopyBtn');
|
|
1104 |
|
1105 |
// Mémorise la dernière instance vue pour détecter les bascules
|
1106 |
window._lastInstanceId = null;
|
|
|
|
|
|
|
1107 |
|
1108 |
|
1109 |
const warmupCloseBtn = document.getElementById('warmupCloseBtn');
|
@@ -1211,64 +1214,62 @@ if (warmupCloseBtn) warmupCloseBtn.addEventListener('click', closeWarmupPopup);
|
|
1211 |
let warmupTimer = null;
|
1212 |
async function refreshWarmupUI(){
|
1213 |
try{
|
1214 |
-
|
1215 |
-
|
1216 |
if(!r.ok) return;
|
1217 |
const s = await r.json();
|
1218 |
|
1219 |
-
|
1220 |
-
// Instance courante (ajout backend)
|
1221 |
const instanceId = s.instance_id || 'n/a';
|
1222 |
if (window._lastInstanceId && window._lastInstanceId !== instanceId) {
|
1223 |
showToast(`Bascule d'instance détectée : ${window._lastInstanceId} → ${instanceId}`);
|
1224 |
}
|
1225 |
window._lastInstanceId = instanceId;
|
1226 |
|
1227 |
-
|
1228 |
-
const pct = Math.max(0, Math.min(100, parseInt(s.percent||0,10)));
|
1229 |
const running = !!s.running;
|
|
|
1230 |
if (warmupStopBtn) warmupStopBtn.style.display = running ? 'inline-block' : 'none';
|
|
|
1231 |
if (warmupStatusEl) {
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
warmupStatusEl.textContent = `⏳ ${pct}% — ${s.current||''} (${idx}/${tot}) [inst:${instanceId}]`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1236 |
} else {
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
const failN = Array.isArray(s.failed_repos) ? s.failed_repos.length : 0;
|
1244 |
-
warmupStatusEl.textContent = `✅ Terminé — ⬛ ${cacheN} • ✅ ${dlN} • ❌ ${failN} / ${tot} [inst:${instanceId}]`;
|
1245 |
-
if (warmupPopupStatus) warmupPopupStatus.textContent = 'Terminé';
|
1246 |
-
if (warmupLogs) warmupLogs.textContent = buildFinalSummary(s);
|
1247 |
-
} else {
|
1248 |
-
const nCache = Number.isFinite(s.audit_count)
|
1249 |
-
? s.audit_count
|
1250 |
-
: (Array.isArray(s.audit_cached) ? s.audit_cached.length : 0);
|
1251 |
-
warmupStatusEl.textContent = nCache > 0
|
1252 |
-
? `✅ Prêt — cache local: ${nCache} [inst:${instanceId}]`
|
1253 |
-
: `Prêt (aucun run)`;
|
1254 |
-
}
|
1255 |
}
|
1256 |
-
|
1257 |
-
}
|
1258 |
|
1259 |
if (warmupProgressFill) warmupProgressFill.style.width = pct + '%';
|
1260 |
if (warmupPopupStatus) warmupPopupStatus.textContent = running ? 'Téléchargement en cours…' : 'Terminé';
|
1261 |
|
1262 |
-
//
|
1263 |
-
// Afficher "préface + logs" uniquement pendant l'exécution,
|
1264 |
-
// le récap final sera posé plus bas quand s.done === true
|
1265 |
if (running && warmupLogs) {
|
1266 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1267 |
warmupLogs.scrollTop = warmupLogs.scrollHeight;
|
1268 |
}
|
1269 |
|
1270 |
-
|
1271 |
-
|
1272 |
if (!userClosedWarmupPopup) openWarmupPopup();
|
1273 |
if (!warmupTimer) warmupTimer = setInterval(refreshWarmupUI, 1000);
|
1274 |
} else {
|
@@ -1352,7 +1353,7 @@ if (warmupStartBtn){
|
|
1352 |
if (warmupTimer) { clearInterval(warmupTimer); warmupTimer = null; }
|
1353 |
|
1354 |
try{
|
1355 |
-
|
1356 |
method:'POST',
|
1357 |
headers:{ 'Content-Type':'application/json' },
|
1358 |
body: JSON.stringify({ models })
|
@@ -1362,15 +1363,18 @@ if (warmupStartBtn){
|
|
1362 |
alert('Échec démarrage: ' + r.status + ' ' + t);
|
1363 |
return;
|
1364 |
}
|
1365 |
-
// Si un warm-up tourne déjà, on l'indique et on passe en mode "suivi"
|
1366 |
-
try {
|
1367 |
-
const payload = await r.json();
|
1368 |
-
if (payload && payload.already_running) {
|
1369 |
-
showToast("Un warm-up est déjà en cours — j'affiche l'état.");
|
1370 |
-
}
|
1371 |
-
} catch(e) { /* no-op */ }
|
1372 |
|
1373 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1374 |
await refreshWarmupUI();
|
1375 |
if (!warmupTimer) warmupTimer = setInterval(refreshWarmupUI, 1000);
|
1376 |
}catch(e){
|
@@ -1501,6 +1505,7 @@ if (launchSelectedBtn){
|
|
1501 |
return;
|
1502 |
}
|
1503 |
if (typeof refreshWarmupUI === 'function') {
|
|
|
1504 |
const id = setInterval(async ()=>{
|
1505 |
await refreshWarmupUI();
|
1506 |
try{
|
|
|
1104 |
|
1105 |
// Mémorise la dernière instance vue pour détecter les bascules
|
1106 |
window._lastInstanceId = null;
|
1107 |
+
// Job courant (pour ignorer d’éventuelles réponses d’un ancien run)
|
1108 |
+
let currentJobId = null;
|
1109 |
+
|
1110 |
|
1111 |
|
1112 |
const warmupCloseBtn = document.getElementById('warmupCloseBtn');
|
|
|
1214 |
let warmupTimer = null;
|
1215 |
async function refreshWarmupUI(){
|
1216 |
try{
|
1217 |
+
const r = await fetch('/warmup/status');
|
|
|
1218 |
if(!r.ok) return;
|
1219 |
const s = await r.json();
|
1220 |
|
1221 |
+
// Instance courante (multi-répliques)
|
|
|
1222 |
const instanceId = s.instance_id || 'n/a';
|
1223 |
if (window._lastInstanceId && window._lastInstanceId !== instanceId) {
|
1224 |
showToast(`Bascule d'instance détectée : ${window._lastInstanceId} → ${instanceId}`);
|
1225 |
}
|
1226 |
window._lastInstanceId = instanceId;
|
1227 |
|
1228 |
+
const pct = Math.max(0, Math.min(100, parseInt(s.percent || 0, 10)));
|
|
|
1229 |
const running = !!s.running;
|
1230 |
+
|
1231 |
if (warmupStopBtn) warmupStopBtn.style.display = running ? 'inline-block' : 'none';
|
1232 |
+
|
1233 |
if (warmupStatusEl) {
|
1234 |
+
const tot = (s.total ?? 0);
|
1235 |
+
if (running) {
|
1236 |
+
const idx = (s.idx ?? 0) + 1;
|
1237 |
warmupStatusEl.textContent = `⏳ ${pct}% — ${s.current||''} (${idx}/${tot}) [inst:${instanceId}]`;
|
1238 |
+
} else if (s.done) {
|
1239 |
+
const cacheN = Array.isArray(s.cache_repos) ? s.cache_repos.length : 0;
|
1240 |
+
const dlN = Array.isArray(s.downloaded_repos) ? s.downloaded_repos.length : 0;
|
1241 |
+
const failN = Array.isArray(s.failed_repos) ? s.failed_repos.length : Math.max(0, tot - (s.ok_count||0));
|
1242 |
+
warmupStatusEl.textContent = `✅ Terminé — ⬛ ${cacheN} • ✅ ${dlN} • ❌ ${failN} / ${tot} [inst:${instanceId}]`;
|
1243 |
+
if (warmupPopupStatus) warmupPopupStatus.textContent = 'Terminé';
|
1244 |
+
if (warmupLogs) warmupLogs.textContent = buildFinalSummary(s);
|
1245 |
} else {
|
1246 |
+
const nCache = Number.isFinite(s.audit_count)
|
1247 |
+
? s.audit_count
|
1248 |
+
: (Array.isArray(s.audit_cached) ? s.audit_cached.length : 0);
|
1249 |
+
warmupStatusEl.textContent = nCache > 0
|
1250 |
+
? `✅ Prêt — cache local: ${nCache} [inst:${instanceId}]`
|
1251 |
+
: `Prêt (aucun run)`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1252 |
}
|
1253 |
+
}
|
|
|
1254 |
|
1255 |
if (warmupProgressFill) warmupProgressFill.style.width = pct + '%';
|
1256 |
if (warmupPopupStatus) warmupPopupStatus.textContent = running ? 'Téléchargement en cours…' : 'Terminé';
|
1257 |
|
1258 |
+
// Logs live dans la popup pendant l’exécution
|
|
|
|
|
1259 |
if (running && warmupLogs) {
|
1260 |
+
const logsTxt = Array.isArray(s.logs) ? s.logs.join('\n') : '';
|
1261 |
+
const asked = Array.isArray(s.asked)
|
1262 |
+
? s.asked
|
1263 |
+
: (Array.isArray(window.lastRequestedModels) ? window.lastRequestedModels : []);
|
1264 |
+
const preface = (warmupPreface && warmupPreface.trim())
|
1265 |
+
? warmupPreface
|
1266 |
+
: ('Demandés (' + asked.length + '):\n' + asked.map(m=>' • '+m).join('\n'));
|
1267 |
+
warmupLogs.textContent = preface + '\n\n' + (logsTxt || '— en cours…');
|
1268 |
warmupLogs.scrollTop = warmupLogs.scrollHeight;
|
1269 |
}
|
1270 |
|
1271 |
+
// Gestion du polling + ouverture/fermeture popup
|
1272 |
+
if (running) {
|
1273 |
if (!userClosedWarmupPopup) openWarmupPopup();
|
1274 |
if (!warmupTimer) warmupTimer = setInterval(refreshWarmupUI, 1000);
|
1275 |
} else {
|
|
|
1353 |
if (warmupTimer) { clearInterval(warmupTimer); warmupTimer = null; }
|
1354 |
|
1355 |
try{
|
1356 |
+
const r = await fetch('/warmup/start', {
|
1357 |
method:'POST',
|
1358 |
headers:{ 'Content-Type':'application/json' },
|
1359 |
body: JSON.stringify({ models })
|
|
|
1363 |
alert('Échec démarrage: ' + r.status + ' ' + t);
|
1364 |
return;
|
1365 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1366 |
|
1367 |
+
// Lecture unique du payload (évite les doublons)
|
1368 |
+
const payload = await r.json().catch(()=>null);
|
1369 |
+
if (payload && payload.already_running) {
|
1370 |
+
showToast("Un warm-up est déjà en cours — j'affiche l'état.");
|
1371 |
+
}
|
1372 |
+
// Mémoriser un éventuel job_id renvoyé
|
1373 |
+
if (payload && (payload.job_id || payload.job)) {
|
1374 |
+
currentJobId = payload.job_id || payload.job;
|
1375 |
+
}
|
1376 |
+
|
1377 |
+
// Rafraîchir l’UI + lancer le polling local
|
1378 |
await refreshWarmupUI();
|
1379 |
if (!warmupTimer) warmupTimer = setInterval(refreshWarmupUI, 1000);
|
1380 |
}catch(e){
|
|
|
1505 |
return;
|
1506 |
}
|
1507 |
if (typeof refreshWarmupUI === 'function') {
|
1508 |
+
|
1509 |
const id = setInterval(async ()=>{
|
1510 |
await refreshWarmupUI();
|
1511 |
try{
|