refactor: deduplicate persistence, add upsert queries, throttle snake saves
- Replace Create+Get+Update with UpsertGame/UpsertSnakeGame queries - Extract free functions (saveGame, loadGame, etc.) from duplicated receiver methods on Store and Instance types - Remove duplicate generateID from snake package, reuse game.GenerateID - Throttle snake game DB writes to every 2s instead of every tick - Fix double-lock in c4game chat handler - Update all code for sqlc pointer types (*string instead of sql.NullString)
This commit is contained in:
@@ -2,11 +2,10 @@ package snake
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"sync"
|
||||
|
||||
"github.com/ryanhamamura/c4/db/repository"
|
||||
"github.com/ryanhamamura/c4/game"
|
||||
)
|
||||
|
||||
type SnakeStore struct {
|
||||
@@ -39,7 +38,7 @@ func (ss *SnakeStore) Create(width, height int, mode GameMode, speed int) *Snake
|
||||
if speed <= 0 {
|
||||
speed = DefaultSpeed
|
||||
}
|
||||
id := generateID(4)
|
||||
id := game.GenerateID(4)
|
||||
sg := &SnakeGame{
|
||||
ID: id,
|
||||
State: &GameState{
|
||||
@@ -63,7 +62,7 @@ func (ss *SnakeStore) Create(width, height int, mode GameMode, speed int) *Snake
|
||||
ss.gamesMu.Unlock()
|
||||
|
||||
if ss.queries != nil {
|
||||
ss.saveSnakeGame(sg) //nolint:errcheck
|
||||
saveSnakeGame(ss.queries, sg) //nolint:errcheck
|
||||
}
|
||||
|
||||
return si
|
||||
@@ -82,12 +81,12 @@ func (ss *SnakeStore) Get(id string) (*SnakeGameInstance, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
sg, err := ss.loadSnakeGame(id)
|
||||
sg, err := loadSnakeGame(ss.queries, id)
|
||||
if err != nil || sg == nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
players, _ := ss.loadSnakePlayers(id)
|
||||
players, _ := loadSnakePlayers(ss.queries, id)
|
||||
if sg.Players == nil {
|
||||
sg.Players = make([]*Player, 8)
|
||||
}
|
||||
@@ -207,8 +206,8 @@ func (si *SnakeGameInstance) Join(player *Player) bool {
|
||||
si.game.Players[slot] = player
|
||||
|
||||
if si.queries != nil {
|
||||
si.saveSnakePlayer(si.game.ID, player) //nolint:errcheck
|
||||
si.saveSnakeGame(si.game) //nolint:errcheck
|
||||
saveSnakePlayer(si.queries, si.game.ID, player) //nolint:errcheck
|
||||
saveSnakeGame(si.queries, si.game) //nolint:errcheck
|
||||
}
|
||||
|
||||
si.notify()
|
||||
@@ -294,16 +293,10 @@ func (si *SnakeGameInstance) CreateRematch() *SnakeGameInstance {
|
||||
si.game.RematchGameID = &newID
|
||||
|
||||
if si.queries != nil {
|
||||
si.saveSnakeGame(si.game) //nolint:errcheck
|
||||
saveSnakeGame(si.queries, si.game) //nolint:errcheck
|
||||
}
|
||||
si.gameMu.Unlock()
|
||||
|
||||
si.notify()
|
||||
return newSI
|
||||
}
|
||||
|
||||
func generateID(size int) string {
|
||||
b := make([]byte, size)
|
||||
_, _ = rand.Read(b)
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user