@@ -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
3030async 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)
144211function getBannerMessage ( env , state , host ) {
145212 const messages = [ ] ;
0 commit comments