mirror of
https://github.com/smittix/intercept.git
synced 2026-04-28 00:30:00 -07:00
feat: add space weather image prefetch and stable cache-busting
Backend: Add /prefetch-images endpoint that warms the image cache in parallel using a thread pool, skipping already-cached images. Frontend: Trigger prefetch on mode init so images load instantly. Replace per-request Date.now() cache-bust with a 5-minute rotating key to allow browser caching aligned with backend max-age. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -304,3 +304,36 @@ def get_image(key: str):
|
|||||||
_cache_set(cache_key, img_data, TTL_IMAGE)
|
_cache_set(cache_key, img_data, TTL_IMAGE)
|
||||||
return Response(img_data, content_type=entry['content_type'],
|
return Response(img_data, content_type=entry['content_type'],
|
||||||
headers={'Cache-Control': 'public, max-age=300'})
|
headers={'Cache-Control': 'public, max-age=300'})
|
||||||
|
|
||||||
|
|
||||||
|
@space_weather_bp.route('/prefetch-images')
|
||||||
|
def prefetch_images():
|
||||||
|
"""Warm the image cache by fetching all whitelisted images in parallel."""
|
||||||
|
# Only fetch images not already cached
|
||||||
|
to_fetch = {}
|
||||||
|
for key, entry in IMAGE_WHITELIST.items():
|
||||||
|
cache_key = f'img_{key}'
|
||||||
|
if _cache_get(cache_key) is None:
|
||||||
|
to_fetch[key] = entry
|
||||||
|
|
||||||
|
if not to_fetch:
|
||||||
|
return jsonify({'status': 'all cached', 'count': 0})
|
||||||
|
|
||||||
|
def _fetch_and_cache(key: str, entry: dict) -> bool:
|
||||||
|
img_data = _fetch_bytes(entry['url'])
|
||||||
|
if img_data:
|
||||||
|
_cache_set(f'img_{key}', img_data, TTL_IMAGE)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
fetched = 0
|
||||||
|
with concurrent.futures.ThreadPoolExecutor(max_workers=6) as executor:
|
||||||
|
futures = {
|
||||||
|
executor.submit(_fetch_and_cache, k, e): k
|
||||||
|
for k, e in to_fetch.items()
|
||||||
|
}
|
||||||
|
for future in concurrent.futures.as_completed(futures):
|
||||||
|
if future.result():
|
||||||
|
fetched += 1
|
||||||
|
|
||||||
|
return jsonify({'status': 'ok', 'fetched': fetched, 'cached': len(IMAGE_WHITELIST) - len(to_fetch)})
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ const SpaceWeather = (function () {
|
|||||||
let _solarImageKey = 'sdo_193';
|
let _solarImageKey = 'sdo_193';
|
||||||
let _drapFreq = 'drap_global';
|
let _drapFreq = 'drap_global';
|
||||||
|
|
||||||
|
/** Stable cache-bust key that rotates every 5 minutes (matches backend max-age). */
|
||||||
|
function _cacheBust() {
|
||||||
|
return 'v=' + Math.floor(Date.now() / 300000);
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Public API
|
// Public API
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
@@ -27,6 +32,8 @@ const SpaceWeather = (function () {
|
|||||||
if (!_initialized) {
|
if (!_initialized) {
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
// Warm the backend image cache in parallel before rendering
|
||||||
|
fetch('/space-weather/prefetch-images').catch(function () {});
|
||||||
refresh();
|
refresh();
|
||||||
_startAutoRefresh();
|
_startAutoRefresh();
|
||||||
}
|
}
|
||||||
@@ -50,7 +57,7 @@ const SpaceWeather = (function () {
|
|||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.onload = function () { frame.innerHTML = ''; frame.appendChild(img); };
|
img.onload = function () { frame.innerHTML = ''; frame.appendChild(img); };
|
||||||
img.onerror = function () { frame.innerHTML = '<div class="sw-empty">Failed to load image</div>'; };
|
img.onerror = function () { frame.innerHTML = '<div class="sw-empty">Failed to load image</div>'; };
|
||||||
img.src = '/space-weather/image/' + key + '?t=' + Date.now();
|
img.src = '/space-weather/image/' + key + '?' + _cacheBust();
|
||||||
img.alt = key;
|
img.alt = key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +71,7 @@ const SpaceWeather = (function () {
|
|||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.onload = function () { frame.innerHTML = ''; frame.appendChild(img); };
|
img.onload = function () { frame.innerHTML = ''; frame.appendChild(img); };
|
||||||
img.onerror = function () { frame.innerHTML = '<div class="sw-empty">Failed to load image</div>'; };
|
img.onerror = function () { frame.innerHTML = '<div class="sw-empty">Failed to load image</div>'; };
|
||||||
img.src = '/space-weather/image/' + key + '?t=' + Date.now();
|
img.src = '/space-weather/image/' + key + '?' + _cacheBust();
|
||||||
img.alt = key;
|
img.alt = key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user