fix: parallelize space weather API fetches to reduce cold-cache latency

The /space-weather/data endpoint made 13 sequential HTTP requests, each
with a 15s timeout, causing 30-195s load times on cold cache. Now uses
ThreadPoolExecutor to fetch all sources concurrently, reducing worst-case
latency to ~15s (single slowest request).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Smittix
2026-03-02 17:51:31 +00:00
parent 27760784a2
commit 7d3cbb7f91
+21 -15
View File
@@ -2,6 +2,7 @@
from __future__ import annotations from __future__ import annotations
import concurrent.futures
import json import json
import time import time
import urllib.error import urllib.error
@@ -259,22 +260,27 @@ IMAGE_WHITELIST: dict[str, dict[str, str]] = {
@space_weather_bp.route('/data') @space_weather_bp.route('/data')
def get_data(): def get_data():
"""Return aggregated space weather data from all sources.""" """Return aggregated space weather data from all sources."""
data = { fetchers = {
'kp_index': _fetch_kp_index(), 'kp_index': _fetch_kp_index,
'kp_forecast': _fetch_kp_forecast(), 'kp_forecast': _fetch_kp_forecast,
'scales': _fetch_scales(), 'scales': _fetch_scales,
'flux': _fetch_flux(), 'flux': _fetch_flux,
'alerts': _fetch_alerts(), 'alerts': _fetch_alerts,
'solar_wind_plasma': _fetch_solar_wind_plasma(), 'solar_wind_plasma': _fetch_solar_wind_plasma,
'solar_wind_mag': _fetch_solar_wind_mag(), 'solar_wind_mag': _fetch_solar_wind_mag,
'xrays': _fetch_xrays(), 'xrays': _fetch_xrays,
'xray_flares': _fetch_xray_flares(), 'xray_flares': _fetch_xray_flares,
'flare_probability': _fetch_flare_probability(), 'flare_probability': _fetch_flare_probability,
'solar_regions': _fetch_solar_regions(), 'solar_regions': _fetch_solar_regions,
'sunspot_report': _fetch_sunspot_report(), 'sunspot_report': _fetch_sunspot_report,
'band_conditions': _fetch_band_conditions(), 'band_conditions': _fetch_band_conditions,
'timestamp': time.time(),
} }
data = {}
with concurrent.futures.ThreadPoolExecutor(max_workers=13) as executor:
futures = {executor.submit(fn): key for key, fn in fetchers.items()}
for future in concurrent.futures.as_completed(futures):
data[futures[future]] = future.result()
data['timestamp'] = time.time()
return jsonify(data) return jsonify(data)