fix(matchmaking): re-enqueue opens a new game, not the caller's own
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 16s
CI / ui (pull_request) Has been skipped
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m8s

A second "random opponent" enqueue with the same variant and per-turn
rule, while the caller's first game was still open (awaiting an
opponent), returned that same open game, so a player could never start a
fresh random game while one was still searching.

Drop the own-open short-circuit (step 1) in store.OpenOrJoin: a
re-enqueue now joins another player's open game or opens a fresh one.
Accumulation stays bounded by MaxActiveQuickGames, which counts open
games. Update the matchmaker/service/store doc comments and
ARCHITECTURE.md, and flip the pinning test to assert the new behavior.
This commit is contained in:
Ilia Denisov
2026-06-18 10:18:44 +02:00
parent 8793bd34f2
commit 9d52885a6e
5 changed files with 39 additions and 40 deletions
+4 -3
View File
@@ -85,9 +85,10 @@ type EnqueueResult struct {
// Enqueue resolves an auto-match request for accountID under variant and the per-turn
// word rule (multipleWords) into the game they enter immediately — a freshly opened
// game awaiting an opponent, the caller's own still-open game (a re-enqueue is
// idempotent), or another player's open game they just joined. When the caller joins
// an existing game, opponent_joined is pushed to that game's waiting starter.
// game awaiting an opponent, or another player's open game they just joined. A
// re-enqueue while already waiting opens another game rather than returning the
// caller's own. When the caller joins an existing game, opponent_joined is pushed to
// that game's waiting starter.
func (m *Matchmaker) Enqueue(ctx context.Context, accountID uuid.UUID, variant engine.Variant, multipleWords bool) (EnqueueResult, error) {
g, joined, err := m.games.OpenOrJoin(ctx, accountID, autoMatchParams(variant, multipleWords), m.openDeadline())
if err != nil {