Public: anyone can read this; the crew can change it.
forked from trevato/cs
A result that did not land says so and is tried again, instead of vanishing #203
Check · Review · Land · Live done — Landed and live in production.
Pushed. `bun run test` (typecheck + 900 tests) passes and the bundles are rebuilt.
shipped production is serving it deploy ae07c2d
Sign in to join this conversation.
new above
offline
Pushed.
bun run test(typecheck + 900 tests) passes and the bundles are rebuilt.---
A round that did not land now says so and is tried again instead of vanishing.
postResultinsrc/client/main.tsno longer drops everything that is notresponse.ok: the frame keeps the one round that has not been accepted — the bytes of the newest result, never a queue, so a retry can never put a stale snapshot over newer numbers — and sends it again on the next round's post and from the frame loop once its backoff is up, with at most one attempt in flight and four attempts in all. A fresh round waits for no backoff (a match scores one every few minutes); only retries do, doubling from 2s, which is what keeps a 429 from being answered with a flood.src/client/pending.tsis the policy alone, plain data in and out: 429, 5xx and a fetch that never answered are this moment and worth another attempt; 422, 409, 400, 403 and 413 are this round and are not retried. It also holds the sentences — three states in four lines: saved, not saved yet and retrying, refused by the server, or unreachable and given up after the cap.src/pages/game.tsrenders that line under#statsasrole="status" aria-live="polite", outside the section because a saved result replaces that whole section with the leaderboard the server sends back, and it is served holding the sentence that is true before anything is posted, so nothing moves when it is filled in.What to look at:
main.test.tsboots the stub host against a fetch that throws then succeeds, one that answers 429 then 200, one that answers 422, a round that is replaced while it is unsent, and a match that ends offline — each asserting the exact line shown and the number of attempts made, including that thirty frames after a 429 make no request at all.pending.test.tspins the rules themselves. Two existing tests gained anawaitbetween rounds: posts are serialised now (one attempt in flight), and those two stepped frames without ever letting a promise settle — the behaviour they assert is unchanged. The app bundle grew 875 raw / 601 gzipped bytes, mostly the sentences a minifier cannot shorten, and fits its ceiling with 2,286 raw to spare; no ceiling moved. Nothing is kept across a visit: a round that never reaches the server before the tab closes is gone, and the line says that rather than promising a queue in storage.🤖 Generated with Claude Code
Closes #102