Skip to content

Commit 2ef0bc9

Browse files
authored
Feat/control panel caching (#328)
* fix: evoting groups * chore: evault caching
1 parent f68b211 commit 2ef0bc9

File tree

3 files changed

+72
-40
lines changed

3 files changed

+72
-40
lines changed

infrastructure/control-panel/src/lib/components/EVaultList.svelte

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,21 @@
99
let cacheStatus: { lastUpdated: number; isStale: boolean; itemCount: number };
1010
1111
onMount(async () => {
12-
console.log('Component mounted, starting to load eVaults...');
1312
try {
1413
loading = true;
15-
console.log('Loading state set to true');
1614
await loadEVaults();
1715
cacheStatus = EVaultService.getCacheStatus();
18-
console.log('Loaded eVaults:', evaults.length, 'items');
1916
} catch (err) {
2017
error = 'Failed to load eVaults';
2118
console.error('Error in onMount:', err);
2219
} finally {
2320
loading = false;
24-
console.log('Loading state set to false');
2521
}
2622
});
2723
2824
async function loadEVaults() {
29-
console.log('loadEVaults called');
3025
try {
3126
evaults = await EVaultService.getEVaults();
32-
console.log('EVaultService returned:', evaults.length, 'items');
3327
cacheStatus = EVaultService.getCacheStatus();
3428
} catch (err) {
3529
console.error('Error loading eVaults:', err);

infrastructure/control-panel/src/lib/services/cacheService.ts

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,19 @@ class CacheService {
5353

5454
async getCachedEVaults(): Promise<EVault[]> {
5555
if (typeof window !== 'undefined') {
56-
// In browser, return null to indicate we need to fetch from server
57-
// This prevents showing "No eVaults found" prematurely
58-
return null as any;
56+
// In browser, try to get from localStorage as a simple cache
57+
try {
58+
const cached = localStorage.getItem('evault-cache');
59+
if (cached) {
60+
const data = JSON.parse(cached);
61+
if (data.evaults && Array.isArray(data.evaults)) {
62+
return data.evaults;
63+
}
64+
}
65+
} catch (error) {
66+
console.log('No localStorage cache available');
67+
}
68+
return [];
5969
}
6070

6171
await this.init();
@@ -77,7 +87,18 @@ class CacheService {
7787

7888
async updateCache(evaults: EVault[]): Promise<void> {
7989
if (typeof window !== 'undefined') {
80-
return; // No-op in browser
90+
// In browser, save to localStorage
91+
try {
92+
const cacheData = {
93+
evaults,
94+
lastUpdated: Date.now(),
95+
isStale: false
96+
};
97+
localStorage.setItem('evault-cache', JSON.stringify(cacheData));
98+
} catch (error) {
99+
console.error('Failed to save to localStorage:', error);
100+
}
101+
return;
81102
}
82103

83104
await this.init();
@@ -105,6 +126,20 @@ class CacheService {
105126

106127
getCacheStatus(): { lastUpdated: number; isStale: boolean; itemCount: number } {
107128
if (typeof window !== 'undefined') {
129+
// In browser, get from localStorage
130+
try {
131+
const cached = localStorage.getItem('evault-cache');
132+
if (cached) {
133+
const data = JSON.parse(cached);
134+
return {
135+
lastUpdated: data.lastUpdated || 0,
136+
isStale: data.isStale || false,
137+
itemCount: data.evaults?.length || 0
138+
};
139+
}
140+
} catch (error) {
141+
console.log('No localStorage cache available');
142+
}
108143
return { lastUpdated: 0, isStale: true, itemCount: 0 };
109144
}
110145

@@ -121,7 +156,13 @@ class CacheService {
121156

122157
async clearCache(): Promise<void> {
123158
if (typeof window !== 'undefined') {
124-
return; // No-op in browser
159+
// In browser, clear localStorage
160+
try {
161+
localStorage.removeItem('evault-cache');
162+
} catch (error) {
163+
console.error('Failed to clear localStorage cache:', error);
164+
}
165+
return;
125166
}
126167

127168
await this.init();

infrastructure/control-panel/src/lib/services/evaultService.ts

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,31 @@ import { cacheService } from './cacheService';
33

44
export class EVaultService {
55
/**
6-
* Get eVaults with stale-while-revalidate caching
7-
* Returns cached data immediately, refreshes in background if stale
6+
* Get eVaults - load from cache first, then fetch fresh data
87
*/
98
static async getEVaults(): Promise<EVault[]> {
10-
// In browser, always fetch from server since caching doesn't work here
11-
if (typeof window !== 'undefined') {
12-
return this.fetchEVaultsDirectly();
13-
}
14-
15-
// On server, use caching
16-
const isStale = await cacheService.isCacheStale();
17-
18-
if (isStale) {
19-
// Cache is stale, refresh in background
20-
this.refreshCacheInBackground();
9+
// First, try to get cached data (fast)
10+
let cachedData: EVault[] = [];
11+
try {
12+
cachedData = await cacheService.getCachedEVaults();
13+
} catch (error) {
14+
console.log('No cached data available');
2115
}
22-
23-
// Return cached data immediately (even if stale)
24-
return await cacheService.getCachedEVaults();
16+
17+
// Fire off fresh request in background (don't wait for it)
18+
this.fetchFreshDataInBackground();
19+
20+
// Return cached data immediately (even if empty)
21+
return cachedData;
2522
}
2623

2724
/**
28-
* Force refresh the cache with fresh data
25+
* Force refresh - get fresh data and update cache
2926
*/
3027
static async forceRefresh(): Promise<EVault[]> {
31-
const evaults = await this.fetchEVaultsDirectly();
32-
await cacheService.updateCache(evaults);
33-
return evaults;
28+
const freshData = await this.fetchEVaultsDirectly();
29+
await cacheService.updateCache(freshData);
30+
return freshData;
3431
}
3532

3633
/**
@@ -48,29 +45,29 @@ export class EVaultService {
4845
}
4946

5047
/**
51-
* Refresh cache in background (non-blocking)
48+
* Fetch fresh data in background and update cache
5249
*/
53-
private static async refreshCacheInBackground(): Promise<void> {
50+
private static async fetchFreshDataInBackground(): Promise<void> {
5451
try {
55-
const evaults = await this.fetchEVaultsDirectly();
56-
await cacheService.updateCache(evaults);
52+
const freshData = await this.fetchEVaultsDirectly();
53+
await cacheService.updateCache(freshData);
5754
} catch (error) {
58-
console.error('Background cache refresh failed:', error);
59-
// Mark cache as stale so next request will try again
60-
await cacheService.markStale();
55+
console.error('Background refresh failed:', error);
6156
}
6257
}
6358

6459
/**
65-
* Fetch eVaults directly from Kubernetes API
60+
* Fetch eVaults directly from API
6661
*/
6762
private static async fetchEVaultsDirectly(): Promise<EVault[]> {
6863
try {
6964
const response = await fetch('/api/evaults');
7065
if (!response.ok) {
7166
throw new Error(`HTTP error! status: ${response.status}`);
7267
}
73-
return await response.json();
68+
const data = await response.json();
69+
// The backend returns { evaults: [...] }
70+
return data.evaults || [];
7471
} catch (error) {
7572
console.error('Failed to fetch eVaults:', error);
7673
throw error;

0 commit comments

Comments
 (0)