Skip to content

Commit 6336a1b

Browse files
committed
enable UPS banner functionality and update UPS message wording
1 parent e166522 commit 6336a1b

File tree

3 files changed

+91
-12
lines changed

3 files changed

+91
-12
lines changed

handle-api.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,27 @@ async function getStateObj(env) {
99

1010
async function setStateObj(env, obj) {
1111
await env.MAINTENANCE_KV.put('MAINTENANCE_STATE', JSON.stringify(obj));
12-
invalidateCache();
12+
await invalidateCache(['MAINTENANCE_STATE']);
1313
}
1414

15-
function invalidateCache() {
15+
async function invalidateCache(keys = ['MAINTENANCE_STATE', 'wan-is-4g', 'ups-on-battery']) {
16+
// Invalidate in-memory cache
1617
if (globalThis.cache) {
1718
globalThis.cache.maintenance = { value: null, ts: 0 };
1819
globalThis.cache.is4g = { value: null, ts: 0 };
1920
globalThis.cache.upsOnBattery = { value: null, ts: 0 };
2021
}
22+
23+
// Invalidate Cloudflare Cache API
24+
try {
25+
const cache = caches.default;
26+
for (const key of keys) {
27+
const cacheUrl = `https://kv-cache.internal/${key}`;
28+
await cache.delete(cacheUrl);
29+
}
30+
} catch (e) {
31+
console.error('Cache API invalidation error:', e);
32+
}
2133
}
2234

2335
async function toggleGlobalMaintenance(env) {
@@ -96,7 +108,7 @@ async function toggle4gMode(env, state) {
96108
return new Response('Fonctionnalité 4G désactivée', { status: 403 });
97109
}
98110
await env.MAINTENANCE_KV.put('wan-is-4g', state.is4gMode ? 'false' : 'true');
99-
invalidateCache();
111+
await invalidateCache(['wan-is-4g']);
100112
return new Response('Mode 4G mis à jour');
101113
}
102114

@@ -109,7 +121,7 @@ async function set4gMode(request, env) {
109121
return new Response('Format attendu: { enabled: true/false }', { status: 400 });
110122
}
111123
await env.MAINTENANCE_KV.put('wan-is-4g', enabled ? 'true' : 'false');
112-
invalidateCache();
124+
await invalidateCache(['wan-is-4g']);
113125
return new Response('Mode 4G mis à jour');
114126
}
115127

@@ -118,7 +130,7 @@ async function toggleUpsMode(env, state) {
118130
return new Response('Fonctionnalité UPS désactivée', { status: 403 });
119131
}
120132
await env.MAINTENANCE_KV.put('ups-on-battery', state.upsOnBattery ? 'false' : 'true');
121-
invalidateCache();
133+
await invalidateCache(['ups-on-battery']);
122134
return new Response('Mode UPS mis à jour');
123135
}
124136

@@ -131,7 +143,7 @@ async function setUpsMode(request, env) {
131143
return new Response('Format attendu: { enabled: true/false }', { status: 400 });
132144
}
133145
await env.MAINTENANCE_KV.put('ups-on-battery', enabled ? 'true' : 'false');
134-
invalidateCache();
146+
await invalidateCache(['ups-on-battery']);
135147
return new Response('Mode UPS mis à jour');
136148
}
137149

worker.js

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,59 @@ const cache = {
2626
upsOnBattery: { value: null, ts: 0 }
2727
};
2828

29-
// Read a single KV key with optional in-memory cache
29+
// Read a single KV key with Cloudflare Cache API + in-memory cache
3030
async function getCachedKvValue(env, cacheEntry, kvKey, useCache, cacheEnabled, cacheTtl, now) {
31+
// Check in-memory cache first (fastest)
3132
if (useCache && cacheEnabled && cacheEntry.value !== null && (now - cacheEntry.ts < cacheTtl)) {
3233
return cacheEntry.value;
3334
}
35+
36+
// Try Cloudflare Cache API (shared between worker instances)
37+
if (useCache && cacheEnabled) {
38+
try {
39+
const cacheUrl = `https://kv-cache.internal/${kvKey}`;
40+
const cache = caches.default;
41+
const cachedResponse = await cache.match(cacheUrl);
42+
43+
if (cachedResponse) {
44+
const value = await cachedResponse.text();
45+
// Update in-memory cache
46+
cacheEntry.value = value;
47+
cacheEntry.ts = now;
48+
return value;
49+
}
50+
} catch (e) {
51+
// Fallback to KV if Cache API fails
52+
console.error('Cache API error:', e);
53+
}
54+
}
55+
56+
// Read from KV
3457
const value = await env.MAINTENANCE_KV.get(kvKey);
58+
59+
// Store in both caches
3560
if (useCache && cacheEnabled) {
61+
// Update in-memory cache
3662
cacheEntry.value = value;
3763
cacheEntry.ts = now;
64+
65+
// Store in Cloudflare Cache API
66+
try {
67+
const cacheUrl = `https://kv-cache.internal/${kvKey}`;
68+
const cache = caches.default;
69+
const response = new Response(value, {
70+
headers: {
71+
'Cache-Control': `max-age=${Math.floor(cacheTtl / 1000)}`,
72+
'Content-Type': 'text/plain'
73+
}
74+
});
75+
await cache.put(cacheUrl, response);
76+
} catch (e) {
77+
// Silent fail on cache storage
78+
console.error('Cache API put error:', e);
79+
}
3880
}
81+
3982
return value;
4083
}
4184

@@ -50,17 +93,28 @@ async function getMaintenanceState(env, host, useCache = true) {
5093
isGlobalMaintenance: false, subdomainsMaintenance: [], bannerSubdomains: [], bannerMessage: ''
5194
});
5295

53-
const is4gMode = await getCachedKvValue(env, cache.is4g, 'wan-is-4g', useCache, cacheEnabled, cacheTtl, now);
54-
const upsOnBattery = await getCachedKvValue(env, cache.upsOnBattery, 'ups-on-battery', useCache, cacheEnabled, cacheTtl, now);
96+
// Conditional reads: only fetch if the feature is enabled (Solution #4)
97+
let is4gMode = null;
98+
let upsOnBattery = null;
99+
100+
if (envIsTrue(env.ENABLE_4G_BANNER)) {
101+
const is4gRaw = await getCachedKvValue(env, cache.is4g, 'wan-is-4g', useCache, cacheEnabled, cacheTtl, now);
102+
is4gMode = is4gRaw === 'true';
103+
}
104+
105+
if (envIsTrue(env.ENABLE_UPS_BANNER)) {
106+
const upsRaw = await getCachedKvValue(env, cache.upsOnBattery, 'ups-on-battery', useCache, cacheEnabled, cacheTtl, now);
107+
upsOnBattery = upsRaw === 'true';
108+
}
55109

56110
return {
57111
isGlobalMaintenance: stateObj.isGlobalMaintenance === true || stateObj.isGlobalMaintenance === 'true',
58112
subdomainsMaintenance: Array.isArray(stateObj.subdomainsMaintenance) ? stateObj.subdomainsMaintenance : [],
59113
isSubdomainMaintenance: Array.isArray(stateObj.subdomainsMaintenance) ? stateObj.subdomainsMaintenance.includes(host) : false,
60114
bannerSubdomains: Array.isArray(stateObj.bannerSubdomains) ? stateObj.bannerSubdomains : [],
61115
bannerMessage: typeof stateObj.bannerMessage === 'string' ? stateObj.bannerMessage : '',
62-
is4gMode: is4gMode === 'true',
63-
upsOnBattery: upsOnBattery === 'true'
116+
is4gMode: is4gMode === true,
117+
upsOnBattery: upsOnBattery === true
64118
};
65119
}
66120

@@ -140,6 +194,19 @@ function envIsTrue(value) {
140194
return value === true || value === 'true';
141195
}
142196

197+
// Invalidate Cache API entries when state changes
198+
async function invalidateCacheApi(keys) {
199+
try {
200+
const cache = caches.default;
201+
for (const key of keys) {
202+
const cacheUrl = `https://kv-cache.internal/${key}`;
203+
await cache.delete(cacheUrl);
204+
}
205+
} catch (e) {
206+
console.error('Cache API invalidation error:', e);
207+
}
208+
}
209+
143210
// Determine which banner message to show, if any (UPS + 4G can combine)
144211
function getBannerMessage(env, state, host) {
145212
const messages = [];

wrangler.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ enabled = false
1818
# Language setting (FR or EN)
1919
LANGUAGE = "FR"
2020
# Enable/disable cache (true/false) for limite api call between this worker and the kv storage, in Cloudflare free plan You have only 100 000 reads per day
21-
ENABLE_CACHE = false
21+
ENABLE_CACHE = true
2222
# Cache duration in ms (default: 60000 = 1 minute)
2323
CACHE_TTL_MS = 60000
2424

0 commit comments

Comments
 (0)