[01] Bucket-first serving: versioned, atomic, edge-cacheable blobs - #18
Open
chondl wants to merge 8 commits into
Open
[01] Bucket-first serving: versioned, atomic, edge-cacheable blobs#18chondl wants to merge 8 commits into
chondl wants to merge 8 commits into
Conversation
Pull the /team/{num} and /team/{num}/{year} payload shaping out of the
route bodies into reusable helpers (verified byte-identical responses)
so the blob export and historical backfill can produce payloads
identical to the API. Adds the HIST_EPOCH constant that versions the
immutable historical blob path.
write_objs now renders the current-year blob set, uploads only blobs
whose content hash changed (copy-on-write, to immutable content-addressed
v2/{path}.{hash} keys with long-lived Cache-Control), and writes
manifest.json last so readers always resolve a complete old or new set,
never a torn mix. Adds a team/{num} blob per active team. Legacy
unversioned paths are still written each cycle for compatibility with
the deployed frontend. The lossy str(Event) upload gate is replaced by
the content hash, which also stops event blobs going stale between
match updates.
One-time script exporting team_years/{year}, events/{year}, event/{key}
and team/{num}/{year} for every past season (2021 skipped) to the
immutable hist/{HIST_EPOCH} path, using the shared site _read_* helpers.
Idempotent per object and resumable via a bucket-side progress
checkpoint.
Blob URLs now resolve through manifest.json: immutable versioned URLs for the current-year set, epoch-prefixed paths for historical years, with no per-request cache-buster. When no manifest exists (backend not yet deployed) fetches fall back to the legacy path plus ?t= buster, and the backend keeps writing legacy paths, so either deploy order works. getTeam, getYearTeamYears, and historical getTeamYear become bucket-first; the two team-match fetches read the event blob and team-year payload instead of API-only endpoints. Expired IndexedDB entries are retained and served as a last resort when both bucket and API fail, instead of rendering an empty page.
F1/F2: the event blob embeds the full year object, whose stats churn every in-season cycle, so content-addressing re-uploaded all ~215 event blobs each cycle (defeating the immutable edge cache). Render an event blob only when its own event/match/team_event content changes (NaN-stable comparison); unchanged events carry forward their prior versioned key and stale year snapshot.
…params A7: a single failed manifest.json fetch no longer pins every client to the uncached legacy ?t= path for a full 60s TTL (a null result is dropped from the cache so the next call retries). toLogicalPath now replaces all ? and & so blob keys with 3+ query params resolve instead of missing to the backend.
… wave
- getMatch: derive the match view from the (bucket-first, edge-cached) event
blob — the match key encodes its event, and the event blob already carries the
match + its team_matches + team_events. Falls back to the /match API when the
blob lacks the match. Removes the Cloud-Run round trip (and its cold-start
tail) from the match page's critical path.
- getTeamYear: start the event-blob fetches as soon as team_to_events resolves
instead of gating them on the whole metadata Promise.all, which included the
large team_years/{year} blob the event wave does not need.
The not-found placeholder waited 8000ms before rendering, leaving a blank content area for 8 full seconds on any nonexistent or slow-to-load entity (/team/99999, /event/2026zzzzz, etc.). The debounce exists only to avoid a flash of the not-found message before data arrives; 1.5s is ample for that while no longer looking like a hung page. (The comment already described the intent as 'one second'; the 8000 value grew from 1000 over prior commits.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replacement for #2, which GitHub auto-closed when its head branch was renamed
bucket-first-serving->cph-bucket-first-serving. Same commits; base is nowcph-master. Part of the cph-staging series.