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
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:
@@ -74,9 +74,11 @@ func TestMatchmakingOpensThenJoins(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestMatchmakingReEnqueueReturnsOwnOpenGame checks a re-enqueue is idempotent: the
|
||||
// caller gets their existing open game rather than a second one.
|
||||
func TestMatchmakingReEnqueueReturnsOwnOpenGame(t *testing.T) {
|
||||
// TestMatchmakingReEnqueueOpensNewGame checks a re-enqueue opens a fresh open game
|
||||
// rather than returning the caller's existing one: tapping "random opponent" again while
|
||||
// still waiting starts a new search instead of bouncing the player back into the pending
|
||||
// game. Both games stay open until an opponent (a human or the reaper's robot) joins each.
|
||||
func TestMatchmakingReEnqueueOpensNewGame(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
clearOpenGames(t)
|
||||
mm := newMatchmaker(t, newRobotService(t, newGameService()), 90*time.Second, 90*time.Second)
|
||||
@@ -90,8 +92,13 @@ func TestMatchmakingReEnqueueReturnsOwnOpenGame(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("re-enqueue: %v", err)
|
||||
}
|
||||
if r2.Game.ID != r1.Game.ID || r2.Matched {
|
||||
t.Fatalf("re-enqueue = (game %s, matched %v), want the same open game %s unmatched", r2.Game.ID, r2.Matched, r1.Game.ID)
|
||||
if r2.Matched || r2.Game.ID == r1.Game.ID {
|
||||
t.Fatalf("re-enqueue = (game %s, matched %v), want a new open game distinct from %s, unmatched", r2.Game.ID, r2.Matched, r1.Game.ID)
|
||||
}
|
||||
for _, g := range []uuid.UUID{r1.Game.ID, r2.Game.ID} {
|
||||
if _, _, status, err := newGameService().Participants(ctx, g); err != nil || status != "open" {
|
||||
t.Fatalf("game %s status = %q err %v, want open", g, status, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user