refactor: remove persister abstraction layer
Some checks failed
CI / Deploy / test (pull_request) Successful in 8s
CI / Deploy / lint (pull_request) Failing after 46s
CI / Deploy / deploy (pull_request) Has been skipped

Inline persistence logic directly into game stores and handlers:
- game/persist.go: DB mapping methods on GameStore and GameInstance
- snake/persist.go: DB mapping methods on SnakeStore and SnakeGameInstance
- Chat persistence inlined into c4game handlers
- Delete db/persister.go (GamePersister, SnakePersister, ChatPersister)
- Stores now take *repository.Queries directly instead of Persister interface
This commit is contained in:
Ryan Hamamura
2026-03-02 12:30:33 -10:00
parent 8c3b3fc6ea
commit 2aa026b1d5
10 changed files with 475 additions and 448 deletions

View File

@@ -1,36 +1,28 @@
package snake
import (
"context"
"crypto/rand"
"encoding/hex"
"sync"
"github.com/ryanhamamura/c4/db/repository"
)
type Persister interface {
SaveSnakeGame(sg *SnakeGame) error
LoadSnakeGame(id string) (*SnakeGame, error)
SaveSnakePlayer(gameID string, player *Player) error
LoadSnakePlayers(gameID string) ([]*Player, error)
DeleteSnakeGame(id string) error
}
type SnakeStore struct {
games map[string]*SnakeGameInstance
gamesMu sync.RWMutex
persister Persister
games map[string]*SnakeGameInstance
gamesMu sync.RWMutex
queries *repository.Queries
notifyFunc func(gameID string)
}
func NewSnakeStore() *SnakeStore {
func NewSnakeStore(queries *repository.Queries) *SnakeStore {
return &SnakeStore{
games: make(map[string]*SnakeGameInstance),
games: make(map[string]*SnakeGameInstance),
queries: queries,
}
}
func (ss *SnakeStore) SetPersister(p Persister) {
ss.persister = p
}
func (ss *SnakeStore) SetNotifyFunc(f func(gameID string)) {
ss.notifyFunc = f
}
@@ -60,18 +52,18 @@ func (ss *SnakeStore) Create(width, height int, mode GameMode, speed int) *Snake
Speed: speed,
}
si := &SnakeGameInstance{
game: sg,
notify: ss.makeNotify(id),
persister: ss.persister,
store: ss,
game: sg,
notify: ss.makeNotify(id),
queries: ss.queries,
store: ss,
}
ss.gamesMu.Lock()
ss.games[id] = si
ss.gamesMu.Unlock()
if ss.persister != nil {
ss.persister.SaveSnakeGame(sg)
if ss.queries != nil {
ss.saveSnakeGame(sg)
}
return si
@@ -86,16 +78,16 @@ func (ss *SnakeStore) Get(id string) (*SnakeGameInstance, bool) {
return si, true
}
if ss.persister == nil {
if ss.queries == nil {
return nil, false
}
sg, err := ss.persister.LoadSnakeGame(id)
sg, err := ss.loadSnakeGame(id)
if err != nil || sg == nil {
return nil, false
}
players, _ := ss.persister.LoadSnakePlayers(id)
players, _ := ss.loadSnakePlayers(id)
if sg.Players == nil {
sg.Players = make([]*Player, 8)
}
@@ -106,10 +98,10 @@ func (ss *SnakeStore) Get(id string) (*SnakeGameInstance, bool) {
}
si = &SnakeGameInstance{
game: sg,
notify: ss.makeNotify(id),
persister: ss.persister,
store: ss,
game: sg,
notify: ss.makeNotify(id),
queries: ss.queries,
store: ss,
}
ss.gamesMu.Lock()
@@ -129,8 +121,8 @@ func (ss *SnakeStore) Delete(id string) error {
si.Stop()
}
if ss.persister != nil {
return ss.persister.DeleteSnakeGame(id)
if ss.queries != nil {
return ss.queries.DeleteSnakeGame(context.Background(), id)
}
return nil
}
@@ -158,14 +150,14 @@ func (ss *SnakeStore) ActiveGames() []*SnakeGame {
}
type SnakeGameInstance struct {
game *SnakeGame
gameMu sync.RWMutex
game *SnakeGame
gameMu sync.RWMutex
pendingDirQueue [8][]Direction // queued directions per slot (max 3)
notify func()
persister Persister
store *SnakeStore
stopCh chan struct{}
loopOnce sync.Once
notify func()
queries *repository.Queries
store *SnakeStore
stopCh chan struct{}
loopOnce sync.Once
}
func (si *SnakeGameInstance) ID() string {
@@ -214,9 +206,9 @@ func (si *SnakeGameInstance) Join(player *Player) bool {
player.Slot = slot
si.game.Players[slot] = player
if si.persister != nil {
si.persister.SaveSnakePlayer(si.game.ID, player)
si.persister.SaveSnakeGame(si.game)
if si.queries != nil {
si.saveSnakePlayer(si.game.ID, player)
si.saveSnakeGame(si.game)
}
si.notify()
@@ -301,8 +293,8 @@ func (si *SnakeGameInstance) CreateRematch() *SnakeGameInstance {
}
si.game.RematchGameID = &newID
if si.persister != nil {
si.persister.SaveSnakeGame(si.game)
if si.queries != nil {
si.saveSnakeGame(si.game)
}
si.gameMu.Unlock()