Commit Graph

60 Commits

Author SHA1 Message Date
Josh Creek 6d3490da14 fix(server): gate proposal participant timeout on actual expiry
ProposalParticipantExpireSQL marked every PENDING participant on a
proposal TIMED_OUT unconditionally -- it took a proposal_id and 'now'
but never actually compared 'now' against the proposal's expires_at,
unlike its sibling ProposalExpireSQL (which does gate on
'expires_at <= $2'). Both GetProposal and RespondToProposal run this
statement on every call as a recovery step, so the very first
RespondToProposal for any proposal timed out every participant
(including the one about to respond) before checking their response,
then rejected the real accept/decline with ErrConflict. Add the same
expiry gate via an EXISTS against proposals.expires_at, matching
ProposalExpireSQL's own condition, and update the SQL-fragment test to
assert the gate is present. Verified end to end against a real
PostgreSQL instance: TestPostgreSQLProposalClaimAndResponseAreAtomic
now passes a two-participant accept/accept sequence that previously
failed on the first response.
2026-09-01 12:44:43 +01:00
Josh Creek e23243ff56 fix(server): drop extra unused argument in queue ticket insert
CreateQueueTicket passed 9 arguments to QueueTicketInsertSQL, which
only has 8 placeholders (state is a hardcoded 'QUEUED' literal in the
SQL, not $4) -- every real queue-ticket creation against PostgreSQL
failed with 'mismatched param and argument count'. Found by actually
running the opt-in Postgres integration suite (previously never
exercised locally, per its own gating) rather than trusting the unit
tests, which mock the driver and can't catch a placeholder-count
mismatch. Verified fixed against a real postgres:17-alpine container.
2026-09-01 12:44:36 +01:00
Josh Creek 67609d71c0 feat(multiplayer): add down migrations and a rollback runner
Add migrations.Rollback(ctx, db, dir, steps): reverses the N most
recently applied migrations, newest first, each in its own committed
transaction under the same advisory lock Apply uses. Down SQL lives in
migrations/down/<version>.sql (a subdirectory, so Apply's *.sql glob
over the main directory is untouched); a missing down file for a
migration being rolled back is a hard error rather than a silent
partial reversal. Wire it into cmd/migrate as --rollback=N.

Add down files for all six existing migrations, each dropping objects
in FK-safe reverse dependency order.

Adversarial review: could not run the new integration test
(TestPostgreSQLMigrationsRollBackAndReapplyCleanly, gated behind
COSMIC_CLASH_POSTGRES_DSN / scripts/run_postgres_integration.sh)
against a real database in this sandbox - Docker Desktop's own
overlayfs ran out of space pulling postgres:17-alpine, unrelated to
this change. Verified instead by hand-tracing every DROP against its
forward migration's FK graph, confirming Apply's directory glob does
not pick up the down/ subdirectory, and a clean go build/vet/test
-tags integration. Worth an explicit real run before this is trusted
in CI.
2026-09-01 12:41:30 +01:00
Josh Creek 7e5cfdeceb style(server): gofmt allocation_match_sql_test.go 2026-09-01 12:41:18 +01:00
Josh Creek d937cb153c feat(multiplayer): add server process/assignment-ready registration API
Add POST /v1/servers/{id}/register (and its /api/v1 contract alias),
authenticated by the same workload binding as the result route. A
game server reports its protocol version and image digest and asks
to advance ALLOCATING -> PROCESS_READY -> ASSIGNMENT_READY; the store
boundary (AdvanceServerRegistration) does this as one idempotent
SERIALIZABLE transaction that also advances every participant's queue
ticket, and gates the final transition on every participant having a
live, unexpired assignment.

Adversarial review of the surrounding routing turned up a pre-existing
bug: contractServerMutation rejected any path containing '/', so the
already-documented /api/v1/servers/{id}/result route (and this new
/register route) 404'd for every real caller despite being declared
in the OpenAPI contract. Fix it to delegate shape validation to
serverMutation, matching how contractQueueMutation handles its own
two-segment paths, and add a regression test covering both contract
routes end to end.
2026-09-01 12:35:30 +01:00
Josh Creek 9dc1cc2d6f feat(multiplayer): refresh allocator ready servers 2026-09-01 10:44:43 +01:00
Josh Creek 013eb0778b fix(multiplayer): advance tickets on allocation bind 2026-09-01 10:42:10 +01:00
Josh Creek 25fdc2c2c8 fix(multiplayer): recover recorded allocations 2026-09-01 10:40:10 +01:00
Josh Creek 55c46f56ec feat(multiplayer): run leased allocator worker 2026-09-01 10:38:45 +01:00
Josh Creek 6f7d61eafb feat(multiplayer): lease allocating match claims 2026-09-01 10:36:13 +01:00
Josh Creek 03ff8e485e feat: promote accepted proposals from API 2026-09-01 10:29:50 +01:00
Josh Creek e0ba6c6ead fix: enforce ranked match promotion size 2026-09-01 10:22:26 +01:00
Josh Creek 7807b9706b feat: promote accepted proposals into matches 2026-09-01 10:21:41 +01:00
Josh Creek 2d750cbcab feat: enable guarded ranked matcher role 2026-09-01 10:14:22 +01:00
Josh Creek d882469c79 feat: repair matcher candidates through redis projection 2026-09-01 10:11:54 +01:00
Josh Creek 7a3d520608 fix: bind rated result to durable receipt 2026-09-01 10:09:40 +01:00
Josh Creek dd80b52a11 feat: apply certified ratings during result completion 2026-09-01 10:08:11 +01:00
Josh Creek 388300c553 fix: validate durable result submissions 2026-09-01 10:02:29 +01:00
Josh Creek eebab1bc19 feat: add workload-authenticated result API 2026-09-01 10:01:04 +01:00
Josh Creek febc69bdef feat: gate allocator roster publication 2026-09-01 09:55:09 +01:00
Josh Creek 8b5b5333c6 fix: verify signed assignment rosters 2026-09-01 09:53:45 +01:00
Josh Creek 55e07648cf test: cover provider allocation reconciliation SQL 2026-09-01 09:52:00 +01:00
Josh Creek 0023bdab6e feat: reconcile Agones allocations durably 2026-09-01 09:51:52 +01:00
Josh Creek 4bbaf0976f feat: add ranked season maintenance role 2026-09-01 09:46:57 +01:00
Josh Creek e729570010 test: cover allocator PostgreSQL claims 2026-09-01 09:45:02 +01:00
Josh Creek b1966a3423 feat: add durable allocator claim boundary 2026-09-01 09:43:33 +01:00
Josh Creek def60169a8 feat: persist authenticated queue probe RTT 2026-09-01 09:40:25 +01:00
Josh Creek 25cc182793 feat: persist queue probe metadata 2026-09-01 09:37:47 +01:00
Josh Creek e170bcf0ef fix: bind matcher source to playlist 2026-09-01 09:35:00 +01:00
Josh Creek d0952adaf9 feat: add runnable casual matcher role 2026-09-01 09:32:22 +01:00
Josh Creek 18888ed520 feat: add PostgreSQL migration runner 2026-09-01 09:21:26 +01:00
Josh Creek 5b80c97337 test: cover PostgreSQL season rollover 2026-09-01 09:06:10 +01:00
Josh Creek bd26aa3dc4 test: cover PostgreSQL result and outbox flow 2026-09-01 09:05:15 +01:00
Josh Creek 9d210d254a test: cover PostgreSQL proposal transactions 2026-09-01 09:04:16 +01:00
Josh Creek c8a542a3af feat: repair Redis candidates from durable source 2026-09-01 09:02:55 +01:00
Josh Creek eadaa7b54e feat: add rebuildable Redis candidate index 2026-09-01 09:01:32 +01:00
Josh Creek 414df530f0 test: expand PostgreSQL adapter coverage 2026-09-01 08:59:39 +01:00
Josh Creek 5234390931 test: add PostgreSQL integration harness 2026-09-01 08:58:28 +01:00
Josh Creek 23134796ee feat: add durable outbox dispatcher 2026-09-01 08:12:33 +01:00
Josh Creek fec4f91672 feat: bind signed rosters to assignments 2026-09-01 08:10:05 +01:00
Josh Creek 63f4f11aa8 feat: publish assignment rosters atomically 2026-09-01 08:08:00 +01:00
Josh Creek f520584368 fix: expire proposals on response boundary 2026-09-01 08:06:17 +01:00
Josh Creek eef7cf28da feat: make proposal responses durable 2026-09-01 07:52:52 +01:00
Josh Creek 30b4560bd5 feat: persist participant-scoped proposal recovery 2026-09-01 07:50:11 +01:00
Josh Creek 3ae2daec88 feat: persist player-scoped assignments 2026-08-31 23:19:23 +01:00
Josh Creek fe246bf54e feat: add replayable outbox adapter 2026-08-31 23:14:33 +01:00
Josh Creek b3284d4bd6 feat: persist authenticated sessions 2026-08-31 22:23:59 +01:00
Josh Creek 59cf29949f feat: wire persistent queue backend into API 2026-08-31 22:17:32 +01:00
Josh Creek b2d68d93cf fix: make SQL queue recovery expire authoritatively 2026-08-31 22:14:30 +01:00
Josh Creek 068b66b234 fix: bind proposal claims to playlist 2026-08-31 22:13:37 +01:00