mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
* fix: persist circuit breaker cache to IndexedDB across page reloads On page reload, all 28+ circuit breaker in-memory caches are lost, triggering 20-30 simultaneous POST requests to Vercel edge functions. Wire the existing persistent-cache.ts (IndexedDB + localStorage + Tauri fallback) into CircuitBreaker so every breaker automatically: - Hydrates from IndexedDB on first execute() call (~1-5ms read) - Writes to IndexedDB fire-and-forget on every recordSuccess() - Falls back to stale persistent data on network failure - Auto-disables for breakers with cacheTtlMs=0 (live pricing) Zero consumer code changes -- all 28+ breaker call sites untouched. Reloads within the cache TTL (default 10min) serve instantly from IndexedDB with zero network calls. Also adds deletePersistentCache() to persistent-cache.ts for clean cache invalidation via clearCache(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add Playwright e2e tests for circuit breaker persistent cache 7 tests covering: IndexedDB persistence on success, hydration on new instance, TTL expiry forcing fresh fetch, 24h stale ceiling rejection, clearCache cleanup, cacheTtlMs=0 auto-disable, and network failure fallback to stale persistent data. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: desktop cache deletion + clearCache race condition P1: deletePersistentCache sent empty string to write_cache_entry, which fails Rust's serde_json::from_str (not valid JSON). Add dedicated delete_cache_entry Tauri command that removes the key from the in-memory HashMap and flushes to disk. P2: clearCache() set persistentLoaded=false, allowing a concurrent execute() to re-hydrate stale data from IndexedDB before the async delete completed. Remove the reset — after explicit clear there is no reason to re-hydrate from persistent storage. * fix: default persistCache to false, fix falsy data guard P1b: 6 breakers store Date objects (weather, aviation, ACLED, military-flights, military-vessels, GDACS) which become strings after JSON round-trip. Callers like MapPopup.getTimeUntil() call date.getTime() on hydrated strings → TypeError. Change default to false (opt-in) so persistence requires explicit confirmation that the payload is JSON-safe. P2: `if (!entry?.data) return` drops valid falsy payloads (0, false, empty string). Use explicit null/undefined check instead. * fix: address blocking review issues on circuit breaker persistence - clearCache() nulls persistentLoadPromise to orphan in-flight hydration - delete_cache_entry defers disk flush to exit handler (avoids 14MB sync write) - hydratePersistentCache checks TTL before setting lastDataState to 'cached' - deletePersistentCache resets cacheDbPromise on IDB error + logs warning - hydration catch logs warning instead of silently swallowing - deletePersistentCache respects isStorageQuotaExceeded() for localStorage --------- Co-authored-by: Elias El Khoury <efk@anghami.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>