gallery_server_client_s190js/public/js/workerStatus.js
2026-10-26 11:00:14 +01:00

138 lines
3.8 KiB
JavaScript

// Contatori di sola lettura delle code dei worker.
(() => {
"use strict";
const container = document.getElementById("workerStatus");
if (!container) return;
const queues = [
{
key: "photos",
errorsKey: "photosErrors",
countId: "workerPhotosCount",
errorsId: "workerPhotosErrors",
label: "Acquisizione delle foto"
},
{
key: "faces",
errorsKey: "facesErrors",
countId: "workerFacesCount",
errorsId: "workerFacesErrors",
label: "Riconoscimento facciale"
},
{
key: "activities",
errorsKey: "activitiesErrors",
countId: "workerActivitiesCount",
errorsId: "workerActivitiesErrors",
label: "Elaborazione attività"
},
{
key: "locations",
errorsKey: "locationsErrors",
countId: "workerLocationsCount",
errorsId: "workerLocationsErrors",
label: "Geolocalizzazione"
}
].map(queue => ({
...queue,
count: document.getElementById(queue.countId),
errors: document.getElementById(queue.errorsId)
}));
if (queues.some(q => !q.count || !q.errors)) return;
let requestInProgress = false;
function isAuthenticated() {
return document.body.classList.contains("authenticated") &&
window.AppAuth &&
typeof window.AppAuth.isLoggedIn === "function" &&
window.AppAuth.isLoggedIn();
}
function number(value) {
const n = Number(value);
return Number.isFinite(n) && n > 0 ? Math.trunc(n) : 0;
}
function formatCount(value) {
const n = number(value);
return n > 9999 ? "9999+" : String(n);
}
async function refreshWorkerCounts() {
if (requestInProgress) return;
if (!isAuthenticated() || !localStorage.getItem("token")) {
container.hidden = true;
return;
}
requestInProgress = true;
try {
const response = await fetch("/scanStatus/worker-queues", {
method: "GET",
cache: "no-store",
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
Accept: "application/json"
}
});
if (response.status === 401 || response.status === 403) {
container.hidden = true;
return;
}
if (!response.ok) throw new Error("HTTP " + response.status);
const data = await response.json();
if (!data.ok) throw new Error("Risposta non valida");
let hasJobsOrErrors = false;
for (const q of queues) {
const jobs = number(data[q.key]);
const errors = number(data[q.errorsKey]);
const item = q.count.parentElement;
q.count.textContent = formatCount(jobs);
q.errors.textContent = formatCount(errors) + " err.";
q.errors.hidden = errors === 0;
item.classList.toggle("has-errors", errors > 0);
item.hidden = jobs === 0 && errors === 0;
item.title = `${q.label}: ${jobs} job da completare, ${errors} job in errore`;
item.setAttribute(
"aria-label",
`${q.label}: ${jobs} job da completare, ${errors} job in errore`
);
hasJobsOrErrors ||= jobs > 0 || errors > 0;
}
container.hidden = !hasJobsOrErrors;
} catch (error) {
console.warn("[worker-status] Aggiornamento non riuscito:", error.message);
} finally {
requestInProgress = false;
}
}
async function startWorkerStatus() {
let seconds = 1;
try {
const config = window.AppConfigPromise
? await window.AppConfigPromise
: (window.AppConfig || {});
const value = Number(config.workerStatusRefreshSeconds);
if (Number.isFinite(value) && value > 0) seconds = value;
} catch (error) {
console.warn("[worker-status] Uso intervallo predefinito:", error.message);
}
refreshWorkerCounts();
window.setInterval(refreshWorkerCounts, seconds * 1000);
}
startWorkerStatus();
})();