From 039af8caac0847d50df734e3ff4af6d56a132c4d Mon Sep 17 00:00:00 2001 From: grabowski Date: Wed, 12 Aug 2026 11:05:02 +0700 Subject: [PATCH] perf: cache /measurements/latest; stale-on-error fallback for cached endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The response caches (HII feeds, and now /measurements/latest at 45s TTL — the endpoint every dashboard poll hits) share one helper, _ttl_cached_stale: single-flight per key, empty results never cached, and expired entries kept as a fallback. If a recompute fails (DB unreachable), the last good response is served with an X-Data-Stale: true header instead of a 5xx — during an outage the dashboard keeps showing the last real readings with their honest timestamps. TTLs: LATEST_CACHE_TTL_SECONDS (45), HII_CACHE_TTL_SECONDS (120). --- src/config.py | 2 + src/web_api.py | 123 ++++++++++++++++++++++++++---------- tests/test_hii_collector.py | 96 +++++++++++++++++++++++----- 3 files changed, 171 insertions(+), 50 deletions(-) diff --git a/src/config.py b/src/config.py index cf53c68..7f78b88 100644 --- a/src/config.py +++ b/src/config.py @@ -88,6 +88,8 @@ class Config: HII_BASIN_CODE = int(os.getenv("HII_BASIN_CODE", "6")) # 6 = Ping Basin # TTL for the /api/hii/*/latest response cache; source data changes hourly HII_CACHE_TTL_SECONDS = int(os.getenv("HII_CACHE_TTL_SECONDS", "120")) + # TTL for the /measurements/latest response cache (hottest endpoint) + LATEST_CACHE_TTL_SECONDS = int(os.getenv("LATEST_CACHE_TTL_SECONDS", "45")) # Umami analytics (self-hosted). The website id is public (it ships in the # dashboard