154 lines
4.0 KiB
JavaScript
154 lines
4.0 KiB
JavaScript
/**
|
|
* LLM Monitor - Data Sync Worker
|
|
* Aggiorna i dati in background e notifica il main thread
|
|
*/
|
|
|
|
const API_BASE = "/api/v1";
|
|
const REFRESH_INTERVAL = 30000; // 30 secondi
|
|
let activeServerId = null;
|
|
let activeHost = null;
|
|
|
|
// Formattare bytes
|
|
function formatBytes(bytes) {
|
|
if (bytes === 0) return "0 B";
|
|
const k = 1024;
|
|
const sizes = ["B", "KB", "MB", "GB"];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return (bytes / Math.pow(k, i)).toFixed(2) + " " + sizes[i];
|
|
}
|
|
|
|
// Recuperare health
|
|
async function fetchHealth() {
|
|
if (!activeHost) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(buildApiUrl(`${API_BASE}/health`));
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
return {
|
|
status: data.status,
|
|
ollama_status: data.ollama_status,
|
|
timestamp: new Date().toISOString(),
|
|
serverId: activeServerId
|
|
};
|
|
}
|
|
} catch (error) {
|
|
console.error("Health check error:", error);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Recuperare modelli
|
|
async function fetchModels() {
|
|
if (!activeHost) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(buildApiUrl(`${API_BASE}/models`));
|
|
if (!response.ok) throw new Error("Failed to load models");
|
|
|
|
const data = await response.json();
|
|
const models = data.models || [];
|
|
|
|
return {
|
|
models,
|
|
total: models.length,
|
|
totalSize: formatBytes(models.reduce((sum, m) => sum + m.size, 0)),
|
|
timestamp: new Date().toISOString(),
|
|
serverId: activeServerId
|
|
};
|
|
} catch (error) {
|
|
console.error("Error loading models:", error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Recuperare dettagli show per un modello
|
|
async function fetchModelShow(modelName) {
|
|
try {
|
|
const response = await fetch(buildApiUrl(`${API_BASE}/models/${encodeURIComponent(modelName)}/show`));
|
|
if (!response.ok) {
|
|
return null;
|
|
}
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error(`Error loading show data for model ${modelName}:`, error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Recuperare dettagli show per tutti i modelli
|
|
async function fetchAllModelsShow(models) {
|
|
const showByModel = {};
|
|
const results = await Promise.allSettled(
|
|
models.map(async (model) => {
|
|
const showData = await fetchModelShow(model.name);
|
|
return { name: model.name, showData };
|
|
})
|
|
);
|
|
|
|
results.forEach((result) => {
|
|
if (result.status === "fulfilled" && result.value.showData) {
|
|
showByModel[result.value.name] = result.value.showData;
|
|
}
|
|
});
|
|
|
|
return showByModel;
|
|
}
|
|
|
|
// Sincronizzare i dati
|
|
async function syncData() {
|
|
if (!activeHost) {
|
|
self.postMessage({
|
|
type: "DATA_UPDATED",
|
|
health: null,
|
|
modelsData: null,
|
|
serverId: activeServerId
|
|
});
|
|
return;
|
|
}
|
|
|
|
const health = await fetchHealth();
|
|
const modelsData = await fetchModels();
|
|
|
|
if (modelsData && modelsData.models.length > 0) {
|
|
modelsData.showByModel = await fetchAllModelsShow(modelsData.models);
|
|
} else if (modelsData) {
|
|
modelsData.showByModel = {};
|
|
}
|
|
|
|
// Notificare il main thread
|
|
// (il main thread gestisce localStorage)
|
|
self.postMessage({
|
|
type: "DATA_UPDATED",
|
|
health,
|
|
modelsData,
|
|
serverId: activeServerId
|
|
});
|
|
}
|
|
|
|
function buildApiUrl(path) {
|
|
const url = new URL(path, self.location.origin);
|
|
url.searchParams.set("host", activeHost);
|
|
return `${url.pathname}${url.search}`;
|
|
}
|
|
|
|
// Pianificare aggiornamenti periodici
|
|
setInterval(syncData, REFRESH_INTERVAL);
|
|
|
|
// Gestire messaggi dal main thread
|
|
self.onmessage = (event) => {
|
|
if (event.data.type === "SET_SERVER") {
|
|
activeServerId = event.data.serverId || null;
|
|
activeHost = event.data.host || null;
|
|
syncData();
|
|
}
|
|
|
|
if (event.data.type === "SYNC_NOW") {
|
|
syncData();
|
|
}
|
|
};
|