refactor: deduplicate persistence, add upsert queries, throttle snake saves
Some checks failed
CI / Deploy / test (pull_request) Failing after 15s
CI / Deploy / lint (pull_request) Failing after 23s
CI / Deploy / deploy (pull_request) Has been skipped

- 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:
Ryan Hamamura
2026-03-02 16:56:29 -10:00
parent 9c3f659e96
commit bc6488f063
14 changed files with 318 additions and 494 deletions

View File

@@ -156,9 +156,6 @@ func HandleGameEvents(store *game.GameStore, nc *nats.Conn, sessions *scs.Sessio
if len(chatMessages) > 50 {
chatMessages = chatMessages[len(chatMessages)-50:]
}
chatMu.Unlock()
chatMu.Lock()
msgs := make([]components.ChatMessage, len(chatMessages))
copy(msgs, chatMessages)
chatMu.Unlock()

View File

@@ -2,10 +2,10 @@ package lobby
import (
"context"
"database/sql"
"fmt"
"net/http"
"strconv"
"time"
"github.com/ryanhamamura/c4/db/repository"
lobbycomponents "github.com/ryanhamamura/c4/features/lobby/components"
@@ -28,16 +28,24 @@ func HandleLobbyPage(queries *repository.Queries, sessions *scs.SessionManager,
var userGames []lobbycomponents.GameListItem
if isLoggedIn {
ctx := context.Background()
games, err := queries.GetUserActiveGames(ctx, sql.NullString{String: userID, Valid: true})
games, err := queries.GetUserActiveGames(ctx, &userID)
if err == nil {
for _, g := range games {
isMyTurn := g.Status == 1 && g.CurrentTurn == g.MyColor
opponentName := ""
if g.OpponentNickname != nil {
opponentName = *g.OpponentNickname
}
var lastPlayed time.Time
if g.UpdatedAt != nil {
lastPlayed = *g.UpdatedAt
}
userGames = append(userGames, lobbycomponents.GameListItem{
ID: g.ID,
Status: int(g.Status),
OpponentName: g.OpponentNickname.String,
OpponentName: opponentName,
IsMyTurn: isMyTurn,
LastPlayed: g.UpdatedAt.Time,
LastPlayed: lastPlayed,
})
}
}