fix(games): reject duplicate queue entries (#117)
Some checks are pending
CI / build (push) Waiting to run
deploy / deploy (push) Waiting to run
test / test (push) Waiting to run

* test(games): reproduce duplicate queue deadlock

* fix(games): reject duplicate queue entries
This commit is contained in:
RissRIce 2026-08-12 22:20:18 -06:00 committed by GitHub
parent be75744248
commit 5a1f5d90db
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 56 additions and 2 deletions

View file

@ -13,6 +13,9 @@ var ErrNoOpponent = errors.New("no opponent found")
// ErrUnknownGame means the requested game id is not in the registry.
var ErrUnknownGame = errors.New("unknown game")
// ErrAlreadyQueued means the same player already has a connection waiting for this game.
var ErrAlreadyQueued = errors.New("player already queued")
// Store persists finished matches and tracks per-game ELO ratings. The SQLite
// store implements it; the matchmaker stays storage-agnostic.
type Store interface {
@ -77,7 +80,11 @@ func (mm *Matchmaker) Play(ctx context.Context, gameID string, io PlayerIO) erro
}
mm.mu.Lock()
if w, waiting := mm.queue[gameID]; waiting && w.io.Name() != io.Name() {
if w, waiting := mm.queue[gameID]; waiting {
if w.io.Name() == io.Name() {
mm.mu.Unlock()
return ErrAlreadyQueued
}
// An opponent is waiting — pair up and run the match.
delete(mm.queue, gameID)
mm.mu.Unlock()