one_d4: give the claim/lease protocol a ClaimRef, and drop a dead parameter - #1441
Conversation
…ameter
Both queue interfaces threaded `(id, owner)` through every write past
ClaimNext — six methods each, two loose string_views that nothing paired.
The type existed already: Poller's Claim holds exactly that, it just was
not the queue's currency.
ClaimRef carries the pair, and Claim/ReanalysisClaim hand one out, so a
holder never spells it again. Its fields deliberately have no default
member initializers: under -Wextra a designated initializer naming only
one of them is a compile error, which is what keeps `{.id = …}` from
fencing against an empty owner.
The fakes are where this shows: an override that ignores the claim now
takes one unnamed ClaimRef instead of two annotated parameters.
Separately, HubHandler::StageGameOverLocked took both a room and its id
and used only the room. Deleted rather than annotated.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ST7XLGWstRE4CfUF84ijKD
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
1d4-web | 792b70a | Commit Preview URL Branch Preview URL |
Aug 23 2026, 03:41 PM |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
iili | 792b70a | Commit Preview URL Branch Preview URL |
Aug 23 2026, 03:42 PM |
Review panelFour read-only agents, four lenses (correctness/control flow; SQL/data/resource safety; tests/docs/CI; altitude). Each hunted then tried to refute. Aggregation re-checked the survivors against the head ( Surviving findings: none. Land as-is. Verified clean
Soft notes (not blockers; fold or ignore)
No inline comments. Approve from here. Review panel via Cursor |
Review panel: the reanalysis test's forwarding fake decomposed ClaimRef and reassembled it fieldwise on every call, where the index pool's equivalent passes it straight through. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ST7XLGWstRE4CfUF84ijKD
Recheck (
|
Follow-up to #1438.
-Wunused-parameterproduced 55 annotations there; this is what two of them were actually pointing at.The signal was in the distribution, not the count
Of the 25 annotated parameters in the worker's tests:
id×8,owner×7,lease×4, everything else ×6. Three quarters of them are the same two values, and not because the fakes are lazy — because both queue interfaces ask for them on every method:ClaimNext(owner, lease) Heartbeat(id, owner, lease) Progress (id, owner, games_indexed) Complete (id, owner, games_indexed) Fail (id, owner, message) HandBack (id, owner) Release (id, owner)ClaimNexthands you a claim; every call after it re-states which claim you meant, as two loosestring_views. Nothing types the pairing — the fencing is a runtime SQL check, per call — so passing them in the wrong order compiles silently.ReanalysisQueuehas the identical shape, so the same six signatures exist twice.The type already existed:
Poller::Claimis{IndexJob job; std::string owner;}, exactly the pair. It just was not the queue's currency.ClaimRef
Both queues take it in place of the two parameters, and
Claim/ReanalysisClaimgrow aref()so a holder never spells the pair out again —queue_.Complete(claim.ref(), report->games_indexed).The missing default member initializers are deliberate. With them,
{.id = x}would compile and fence against an empty owner. Without them, #1438's-Wextramakes that a compile error, so a designated initializer has to name both. The two flags compose into something neither gives alone; the header says so, since it otherwise reads like an oversight.Direct call sites use designated initializers (
{.id = Id(1), .owner = "worker-2"}), which is where the swap protection actually lands — a positional{a, b}would still be order-dependent.What it does to the fakes
An override that ignores the claim now takes one unnamed parameter instead of two annotated ones:
Repo-wide
[[maybe_unused]]count falls from 56 to 41, and the diff is net -22 lines across 19 files despite adding a header.The dead parameter
HubHandler::StageGameOverLocked(room_id, room, game_id, outbox)took a room and that room's id, and used only the room. Deleted rather than annotated — this one was-Wunused-parameterfinding genuine dead weight, which is the case for keeping the check on.Scope: this is not #1417
#1417 wants the claim/lease SQL shared, and argues conformance-test-first because "refactoring first means refactoring under no test that would notice if it changed behavior." That ordering applies here too, so I checked before touching anything rather than after:
pg_queue_testalready hasCompleteIsFencedOnOwnership,ProgressIsFencedOnOwnershipToo,FailIsFencedOnOwnershipToo,HandBackAndReleaseAreFencedToo, plus the lease-expiry pair. The fencing is covered; a swap would be caught.This change is signature-only — no SQL text, no predicate, no
SETclause moves. #1417's conformance suite andLeasedTableare untouched and still wanted;ClaimRefis what its parameter lists would be built on.Verified
The gated suites actually ran.
PG_TEST_DB_URLandGOLF_HUB_TEST_DB_URLare unset by default and those suitesGTEST_SKIPsilently, so a green local run proves nothing about the SQL — which is the entire surface this refactor touches. I brought up a local Postgres 16 and confirmed the counts rather than the exit code:pg_queue_testreanalysis_queue_testgame_state_jsonb_testbazel test //domains/... //bazel/...with both URLs supplied: 218 tests pass, zero diagnostics from first-party files.Mutation-checked. Swapping the pairing —
ref()returning{.id = owner, .owner = job.id}— compiles (both are string-ish, which is the point) and failspoller_test. So the pairing is defended by a test, not just by the type.The only build failure is
@raylib//:raylib_cmake, which needslibxrandrheaders this sandbox lacks; unrelated and CI builds it.Review panel
Not run. Flagging that rather than letting the section header imply otherwise — the evidence here is the mutation check and the gated suites above.
🤖 Generated with Claude Code
https://claude.ai/code/session_01ST7XLGWstRE4CfUF84ijKD
Generated by Claude Code