Files
gralias/crons/main.go
2025-07-04 14:30:13 +03:00

136 lines
3.5 KiB
Go

package crons
import (
"context"
"gralias/repos"
"log/slog"
"time"
)
type CronManager struct {
repo repos.AllRepos
log *slog.Logger
}
func NewCronManager(repo repos.AllRepos, log *slog.Logger) *CronManager {
return &CronManager{
repo: repo,
log: log,
}
}
func (cm *CronManager) Start() {
ticker := time.NewTicker(30 * time.Second)
go func() {
for range ticker.C {
cm.CleanupRooms()
cm.CleanupActions()
}
}()
}
func (cm *CronManager) CleanupRooms() {
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 {
cm.log.Error("failed to delete empty room", "room_id", room.ID, "err", err)
}
if err := cm.repo.SettingsDeleteByRoomID(ctx, room.ID); err != nil {
cm.log.Error("failed to delete settings for empty room", "room_id", room.ID, "err", err)
}
continue
}
creatorInRoom := false
for _, player := range players {
if player.Username == room.CreatorName {
creatorInRoom = true
break
}
}
if !creatorInRoom {
cm.log.Info("deleting room because creator left", "room_id", room.ID)
for _, player := range players {
if player.IsBot {
if err := cm.repo.PlayerDelete(ctx, room.ID, player.Username); err != nil {
cm.log.Error("failed to delete bot player", "room_id", room.ID, "username", player.Username, "err", err)
}
} else {
if err := cm.repo.PlayerExitRoom(ctx, player.Username); err != nil {
cm.log.Error("failed to update player room", "room_id", room.ID, "username", player.Username, "err", err)
}
}
}
if err := cm.repo.RoomDeleteByID(ctx, room.ID); err != nil {
cm.log.Error("failed to delete room after creator left", "room_id", room.ID, "err", err)
}
if err := cm.repo.SettingsDeleteByRoomID(ctx, room.ID); err != nil {
cm.log.Error("failed to delete settings after creator left", "room_id", room.ID, "err", err)
}
}
}
if err := tx.Commit(); err != nil {
cm.log.Error("failed to commit transaction", "err", err)
}
}
func (cm *CronManager) CleanupActions() {
ctx, tx, err := cm.repo.InitTx(context.Background())
if err != nil {
cm.log.Error("failed to init transaction for actions cleanup", "err", err)
return
}
defer func() {
if r := recover(); r != nil {
if err := tx.Rollback(); err != nil {
cm.log.Error("failed to rollback transaction for actions cleanup", "err", err)
}
panic(r)
}
}()
if err := cm.repo.ActionDeleteOrphaned(ctx); err != nil {
cm.log.Error("failed to delete orphaned actions", "err", err)
if err := tx.Rollback(); err != nil {
cm.log.Error("failed to rollback transaction for actions cleanup", "err", err)
}
return
}
if err := tx.Commit(); err != nil {
cm.log.Error("failed to commit transaction for actions cleanup", "err", err)
}
}