From efe0c241ab573855150323fb417515f434a70b68 Mon Sep 17 00:00:00 2001 From: Shekhar Vaidya Date: Mon, 18 May 2026 23:34:21 +0530 Subject: [PATCH] =?UTF-8?q?chore:=20update=20CLAUDE.md=20=E2=80=94=20mark?= =?UTF-8?q?=20#12=20and=20Beyond=20#12=20items=20complete,=20defer=20rate?= =?UTF-8?q?=20limiter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 1f61784..9222704 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,34 +16,17 @@ controlled by `CF_WORKER_URL` + `CF_WORKER_SECRET` env vars on the backend. ## Backlog (implement when ready, in priority order) -### #12 — Two-layer in-memory caching (backend/main.go only) +### #12 — Two-layer in-memory caching ✅ DONE (feat/caching-layer, merged) -Goal: reduce Microsoft API traffic from thousands/day to ~50–100/day, -eliminating the 715-123130 rate-limit block under real traffic. - -- [ ] **1. Singleflight** — `golang.org/x/sync/singleflight` wrapping all Microsoft fetches. - Prevents cache stampede: 500 concurrent cache misses → 1 Microsoft hit. -- [ ] **2. SKU info cache** — 7-day TTL, keyed by `product_id`. - Language lists are stable; no need to hit Microsoft on every page load. -- [ ] **3. Download link cache** — ~22h TTL, keyed by `product_id:sku_id`. - Signed URLs are not IP-bound — safe to serve the same link to all users. -- [ ] **4. Negative response caching** — cache 429 / 715-123130 failures for 30–60s. - Prevents thundering herd from retries worsening an existing block. -- [ ] **5. Dynamic TTL** — parse expiry from Microsoft's signed URL instead of fixed 22h. - Derive as: `(link_expiry - now) - 30min`. Safer against clock skew. - Store `cached_at` + `expires_at` metadata with each entry. -- [ ] **6. Stale-on-failure** — if refresh fails (rate-limited/transient), serve stale link - temporarily and retry refresh in background. Prevents global outages. -- [ ] **7. Jitter** — add ±few minutes random offset to TTLs. - Prevents synchronized mass-expiry spikes. +All 7 items shipped: singleflight, SKU cache (7d TTL), link cache (dynamic TTL from `se` param), +negative cache (60s), dynamic TTL, stale-on-failure, jitter. Verified in production. ### Beyond #12 — Observability & resilience -- [ ] **Per-IP / per-product rate limiter** on the backend as extra protection against abuse. -- [ ] **Cache hit/miss logging** — extend existing request logs to show cache hits vs Microsoft calls. -- [ ] **`/metrics` endpoint** (auth-protected) — expose cache hit rate, miss count, stale serves. -- [ ] **README architecture section** — document the caching layer once implemented - (CF Worker section already done, extend for caching). +- [x] **Cache hit/miss logging** — logged on every request (fetched vs cached, cached until timestamp). +- [x] **`/metrics` endpoint** (auth-protected) — exposes cache hit rate, miss count, stale serves. Auth via `METRICS_SECRET` env var. (feat/metrics, merged) +- [x] **README architecture section** — caching layer, `/metrics`, env vars documented. +- [ ] **Per-IP / per-product rate limiter** — deferred; revisit after 1 month of production traffic data. ### Known bugs / open issues