feat: implement cache system and refresh button to avoid unnecessary cluster re-analysis

This commit is contained in:
2025-10-16 09:30:34 -03:00
parent 0243062889
commit 1518bb9f2c

View File

@@ -76,6 +76,48 @@
gap: 16px; gap: 16px;
} }
.refresh-button {
background: transparent;
border: 1px solid var(--pf-global--Color--400);
color: var(--pf-global--Color--200);
padding: 8px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: all 0.2s ease;
display: flex;
align-items: center;
gap: 6px;
}
.refresh-button:hover {
background-color: rgba(255, 255, 255, 0.1);
border-color: var(--pf-global--Color--100);
color: var(--pf-global--Color--100);
}
.refresh-button:active {
transform: scale(0.98);
}
.refresh-button i {
font-size: 12px;
}
.refresh-button.loading i {
animation: spin 1s linear infinite;
}
.refresh-button.loading {
opacity: 0.7;
cursor: not-allowed;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.hamburger-menu { .hamburger-menu {
color: var(--pf-global--Color--100); color: var(--pf-global--Color--100);
font-size: 18px; font-size: 18px;
@@ -1252,6 +1294,10 @@
<a href="#" class="openshift-logo">ORU Analyzer</a> <a href="#" class="openshift-logo">ORU Analyzer</a>
</div> </div>
<div class="openshift-header-right"> <div class="openshift-header-right">
<button class="refresh-button" id="refreshButton" title="Refresh cluster analysis">
<i class="fas fa-sync-alt"></i>
<span>Refresh</span>
</button>
<div class="header-icon"> <div class="header-icon">
<i class="fas fa-question-circle"></i> <i class="fas fa-question-circle"></i>
</div> </div>
@@ -1720,6 +1766,52 @@
// Global variables // Global variables
let currentData = null; let currentData = null;
let currentSection = 'workload-scanner'; let currentSection = 'workload-scanner';
// Cache system
let clusterCache = {
data: null,
timestamp: null,
ttl: 5 * 60 * 1000, // 5 minutes TTL
isAnalyzing: false
};
// Cache utility functions
function isCacheValid() {
if (!clusterCache.data || !clusterCache.timestamp) {
return false;
}
const now = Date.now();
return (now - clusterCache.timestamp) < clusterCache.ttl;
}
function setCacheData(data) {
clusterCache.data = data;
clusterCache.timestamp = Date.now();
clusterCache.isAnalyzing = false;
}
function clearCache() {
clusterCache.data = null;
clusterCache.timestamp = null;
clusterCache.isAnalyzing = false;
}
function getCachedData() {
return clusterCache.data;
}
function setRefreshButtonLoading(loading) {
const refreshButton = document.getElementById('refreshButton');
if (refreshButton) {
if (loading) {
refreshButton.classList.add('loading');
refreshButton.disabled = true;
} else {
refreshButton.classList.remove('loading');
refreshButton.disabled = false;
}
}
}
let loadingState = { let loadingState = {
dashboard: false, dashboard: false,
charts: { charts: {
@@ -1749,9 +1841,24 @@
// Setup navigation // Setup navigation
setupNavigation(); setupNavigation();
// Setup refresh button
setupRefreshButton();
// Load initial data // Load initial data
loadWorkloadScanner(); loadWorkloadScanner();
} }
function setupRefreshButton() {
const refreshButton = document.getElementById('refreshButton');
if (refreshButton) {
refreshButton.addEventListener('click', function(e) {
e.preventDefault();
console.log('Manual refresh triggered');
clearCache();
loadWorkloadScanner(true);
});
}
}
// Loading Functions // Loading Functions
function showFullscreenLoading(message = 'Analyzing Cluster Resources', submessage = 'Please wait while we analyze your cluster resources...') { function showFullscreenLoading(message = 'Analyzing Cluster Resources', submessage = 'Please wait while we analyze your cluster resources...') {
@@ -1968,7 +2075,7 @@
// Load section data // Load section data
if (section === 'workload-scanner') { if (section === 'workload-scanner') {
loadWorkloadScanner(); loadWorkloadScanner(false); // Use cache if available
} else if (section === 'requests-limits') { } else if (section === 'requests-limits') {
loadRequestsLimits(); loadRequestsLimits();
} else if (section === 'vpa-management') { } else if (section === 'vpa-management') {
@@ -2004,8 +2111,28 @@
} }
} }
async function loadWorkloadScanner() { async function loadWorkloadScanner(forceRefresh = false) {
try { try {
// Check cache first (unless force refresh)
if (!forceRefresh && isCacheValid() && !clusterCache.isAnalyzing) {
console.log('Using cached cluster data');
const cachedData = getCachedData();
updateMetricsCards(cachedData);
currentData = { cluster: cachedData };
await loadDashboardCharts();
return;
}
// If already analyzing, don't start another analysis
if (clusterCache.isAnalyzing) {
console.log('Analysis already in progress, waiting...');
return;
}
// Mark as analyzing
clusterCache.isAnalyzing = true;
setRefreshButtonLoading(true);
// Show fullscreen loading modal // Show fullscreen loading modal
showFullscreenLoading( showFullscreenLoading(
'Analyzing Cluster Resources', 'Analyzing Cluster Resources',
@@ -2057,6 +2184,9 @@
} else if (statusData.state === 'SUCCESS') { } else if (statusData.state === 'SUCCESS') {
updateSmartProgress(100, 'Analysis completed successfully!'); updateSmartProgress(100, 'Analysis completed successfully!');
// Save to cache
setCacheData(statusData.result);
// Update metrics cards with results // Update metrics cards with results
updateMetricsCards(statusData.result); updateMetricsCards(statusData.result);
@@ -2086,12 +2216,17 @@
// Hide loading modal // Hide loading modal
hideFullscreenLoading(); hideFullscreenLoading();
stopSmartLoading(); stopSmartLoading();
setRefreshButtonLoading(false);
} catch (error) { } catch (error) {
console.error('Error in batch processing workflow:', error); console.error('Error in batch processing workflow:', error);
hideFullscreenLoading(); hideFullscreenLoading();
stopSmartLoading(); stopSmartLoading();
// Clear analyzing flag on error
clusterCache.isAnalyzing = false;
setRefreshButtonLoading(false);
if (error.name === 'AbortError') { if (error.name === 'AbortError') {
console.error('Request timeout - API stopped responding'); console.error('Request timeout - API stopped responding');
} else { } else {