Enha: tx for cron
This commit is contained in:
@ -29,18 +29,36 @@ func (cm *CronManager) Start() {
|
||||
}
|
||||
|
||||
func (cm *CronManager) CleanupRooms() {
|
||||
ctx := context.Background()
|
||||
ctx, tx, err := cm.repo.InitTx(context.Background())
|
||||
if err != nil {
|
||||
cm.log.Error("failed to init transaction", "err", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
if err := tx.Rollback(); err != nil {
|
||||
cm.log.Error("failed to rollback transaction", "err", err)
|
||||
}
|
||||
panic(r)
|
||||
}
|
||||
}()
|
||||
|
||||
rooms, err := cm.repo.RoomList(ctx)
|
||||
if err != nil {
|
||||
cm.log.Error("failed to get rooms list", "err", err)
|
||||
if err := tx.Rollback(); err != nil {
|
||||
cm.log.Error("failed to rollback transaction", "err", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
for _, room := range rooms {
|
||||
players, err := cm.repo.PlayerListByRoom(ctx, room.ID)
|
||||
if err != nil {
|
||||
cm.log.Error("failed to get players for room", "room_id", room.ID, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(players) == 0 {
|
||||
cm.log.Info("deleting empty room", "room_id", room.ID)
|
||||
if err := cm.repo.RoomDeleteByID(ctx, room.ID); err != nil {
|
||||
@ -48,6 +66,7 @@ func (cm *CronManager) CleanupRooms() {
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
creatorInRoom := false
|
||||
for _, player := range players {
|
||||
if player.Username == room.CreatorName {
|
||||
@ -55,6 +74,7 @@ func (cm *CronManager) CleanupRooms() {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !creatorInRoom {
|
||||
cm.log.Info("deleting room because creator left", "room_id", room.ID)
|
||||
for _, player := range players {
|
||||
@ -73,4 +93,9 @@ func (cm *CronManager) CleanupRooms() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
cm.log.Error("failed to commit transaction", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,41 +47,9 @@ func notifyBotIfNeeded(room *models.Room) {
|
||||
}
|
||||
}
|
||||
|
||||
// cache
|
||||
|
||||
// func saveState(username string, state *models.UserState) error {
|
||||
// key := models.CacheStatePrefix + username
|
||||
// data, err := json.Marshal(state)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// memcache.Set(key, data)
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// func getAllNames() []string {
|
||||
// names := []string{}
|
||||
// // will not scale
|
||||
// session := &models.Session{}
|
||||
// // filter by key size only sessions
|
||||
// for _, name := range wholeMemStore {
|
||||
// // xid is 20 in len
|
||||
// if len(k) != 20 {
|
||||
// continue
|
||||
// }
|
||||
// if err := json.Unmarshal(v, &session); err != nil {
|
||||
// log.Error("failed to unmarshal", "error", err)
|
||||
// continue
|
||||
// }
|
||||
// names = append(names, session.Username)
|
||||
// }
|
||||
// return names
|
||||
// }
|
||||
|
||||
// can room exists without state? I think no
|
||||
func getFullInfoByCtx(ctx context.Context) (*models.FullInfo, error) {
|
||||
resp := &models.FullInfo{}
|
||||
// state, err := getStateByCtx(ctx)
|
||||
state, err := getPlayerByCtx(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -251,7 +251,7 @@ func HandleStartGame(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func HandleJoinRoom(w http.ResponseWriter, r *http.Request) {
|
||||
roomID := r.URL.Query().Get("id")
|
||||
room, err := repo.RoomGetByID(r.Context(), roomID)
|
||||
room, err := repo.RoomGetExtended(r.Context(), roomID)
|
||||
if err != nil {
|
||||
abortWithError(w, err.Error())
|
||||
return
|
||||
|
4
main.go
4
main.go
@ -62,20 +62,16 @@ func main() {
|
||||
// Setup graceful shutdown
|
||||
stop := make(chan os.Signal, 1)
|
||||
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
repo := repos.NewRepoProvider(cfg.DBPath)
|
||||
defer repo.Close()
|
||||
|
||||
cm := crons.NewCronManager(repo, slog.Default())
|
||||
cm.Start()
|
||||
|
||||
server := ListenToRequests(cfg.ServerConfig.Port)
|
||||
go func() {
|
||||
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
<-stop
|
||||
slog.Info("Shutting down server...")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
|
@ -2,6 +2,7 @@ package repos
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"gralias/models"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
@ -60,10 +61,17 @@ func (p *RepoProvider) PlayerDelete(ctx context.Context, roomID, username string
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *RepoProvider) PlayerSetRoomID(ctx context.Context, username, roomID string) error {
|
||||
func (p *RepoProvider) PlayerSetRoomID(ctx context.Context, roomID, username string) error {
|
||||
db := getDB(ctx, p.DB)
|
||||
_, err := db.ExecContext(ctx, "UPDATE players SET room_id = ? WHERE username = ?", roomID, username)
|
||||
return err
|
||||
res, err := db.ExecContext(ctx, "UPDATE players SET room_id = ? WHERE username = ?", roomID, username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
affected, _ := res.RowsAffected()
|
||||
if affected == 0 {
|
||||
return fmt.Errorf("failed to set room_id (%s) for player (%s)", roomID, username)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *RepoProvider) PlayerExitRoom(ctx context.Context, username string) error {
|
||||
|
Reference in New Issue
Block a user