Enha: cron for cleaning rooms from players
This commit is contained in:
@ -27,7 +27,7 @@ func (cm *CronManager) Start() {
|
|||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
cm.CleanupRooms()
|
cm.CleanupRooms()
|
||||||
cm.CleanupActions()
|
cm.CleanupActions()
|
||||||
cm.CleanupInactiveRooms()
|
cm.CleanupPlayersRoom()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -71,6 +71,7 @@ func (cm *CronManager) CleanupRooms() {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
creatorInRoom := false
|
creatorInRoom := false
|
||||||
for _, player := range players {
|
for _, player := range players {
|
||||||
if player.Username == room.CreatorName {
|
if player.Username == room.CreatorName {
|
||||||
@ -78,8 +79,32 @@ func (cm *CronManager) CleanupRooms() {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !creatorInRoom {
|
|
||||||
cm.log.Info("deleting room because creator left", "room_id", room.ID)
|
isInactive := false
|
||||||
|
// If the creator is in the room and the room is more than one hour old, check for inactivity
|
||||||
|
if creatorInRoom && time.Since(room.CreatedAt) > time.Hour {
|
||||||
|
lastActionTime, err := cm.repo.ActionGetLastTimeByRoomID(ctx, room.ID)
|
||||||
|
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||||
|
cm.log.Error("failed to get last action time for room", "room_id", room.ID, "err", err)
|
||||||
|
// Skip setting isInactive and proceed
|
||||||
|
} else {
|
||||||
|
// If there are no actions, lastActionTime is the zero value (or from sql.ErrNoRows we get zero as well)
|
||||||
|
if lastActionTime.IsZero() {
|
||||||
|
isInactive = true
|
||||||
|
} else if time.Since(lastActionTime) > time.Hour {
|
||||||
|
isInactive = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the creator is not in the room or the room is inactive, it's time to delete
|
||||||
|
if !creatorInRoom || isInactive {
|
||||||
|
reason := "creator left"
|
||||||
|
if isInactive {
|
||||||
|
reason = "inactive"
|
||||||
|
}
|
||||||
|
cm.log.Info("deleting room", "room_id", room.ID, "reason", reason)
|
||||||
|
|
||||||
for _, player := range players {
|
for _, player := range players {
|
||||||
if player.IsBot {
|
if player.IsBot {
|
||||||
if err := cm.repo.PlayerDelete(ctx, room.ID, player.Username); err != nil {
|
if err := cm.repo.PlayerDelete(ctx, room.ID, player.Username); err != nil {
|
||||||
@ -91,12 +116,16 @@ func (cm *CronManager) CleanupRooms() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cm.repo.RoomDeleteByID(ctx, room.ID); err != nil {
|
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)
|
cm.log.Error("failed to delete room", "room_id", room.ID, "reason", reason, "err", err)
|
||||||
}
|
}
|
||||||
if err := cm.repo.SettingsDeleteByRoomID(ctx, room.ID); err != nil {
|
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)
|
cm.log.Error("failed to delete settings for room", "room_id", room.ID, "reason", reason, "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move to the next room
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := tx.Commit(); err != nil {
|
if err := tx.Commit(); err != nil {
|
||||||
@ -129,50 +158,3 @@ func (cm *CronManager) CleanupActions() {
|
|||||||
cm.log.Error("failed to commit transaction for actions cleanup", "err", err)
|
cm.log.Error("failed to commit transaction for actions cleanup", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cm *CronManager) CleanupInactiveRooms() {
|
|
||||||
ctx, tx, err := cm.repo.InitTx(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
cm.log.Error("failed to init transaction for inactive rooms 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 inactive rooms cleanup", "err", err)
|
|
||||||
}
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
rooms, err := cm.repo.RoomList(ctx)
|
|
||||||
if err != nil {
|
|
||||||
cm.log.Error("failed to get rooms list for inactive rooms cleanup", "err", err)
|
|
||||||
if err := tx.Rollback(); err != nil {
|
|
||||||
cm.log.Error("failed to rollback transaction for inactive rooms cleanup", "err", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, room := range rooms {
|
|
||||||
lastActionTime, err := cm.repo.ActionGetLastTimeByRoomID(ctx, room.ID)
|
|
||||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
||||||
cm.log.Error("failed to get last action time for room", "room_id", room.ID, "err", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if lastActionTime.IsZero() && time.Since(room.CreatedAt) > time.Hour {
|
|
||||||
cm.log.Info("deleting inactive room (no actions)", "room_id", room.ID, "created_at", room.CreatedAt)
|
|
||||||
if err := cm.repo.RoomDeleteByID(ctx, room.ID); err != nil {
|
|
||||||
cm.log.Error("failed to delete inactive room (no actions)", "room_id", room.ID, "err", err)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !lastActionTime.IsZero() && time.Since(lastActionTime) > time.Hour && time.Since(room.CreatedAt) > time.Hour {
|
|
||||||
cm.log.Info("deleting inactive room (last action older than 1 hour)", "room_id", room.ID, "last_action_time", lastActionTime)
|
|
||||||
if err := cm.repo.RoomDeleteByID(ctx, room.ID); err != nil {
|
|
||||||
cm.log.Error("failed to delete inactive room (last action older than 1 hour)", "room_id", room.ID, "err", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := tx.Commit(); err != nil {
|
|
||||||
cm.log.Error("failed to commit transaction for inactive rooms cleanup", "err", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
58
crons/players.go
Normal file
58
crons/players.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package crons
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
func (cm *CronManager) CleanupPlayersRoom() {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
players, err := cm.repo.PlayerListAll(ctx)
|
||||||
|
if err != nil {
|
||||||
|
cm.log.Error("failed to list players", "err", err)
|
||||||
|
if err := tx.Rollback(); err != nil {
|
||||||
|
cm.log.Error("failed to rollback transaction for actions cleanup", "err", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// get all rooms to have only one req
|
||||||
|
rooms, err := cm.repo.RoomList(ctx)
|
||||||
|
if err != nil {
|
||||||
|
cm.log.Error("failed to list rooms", "err", err)
|
||||||
|
if err := tx.Rollback(); err != nil {
|
||||||
|
cm.log.Error("failed to rollback transaction for actions cleanup", "err", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, player := range players {
|
||||||
|
found := false
|
||||||
|
for _, room := range rooms {
|
||||||
|
// check if room exists
|
||||||
|
if player.RoomID != nil && room.ID == *player.RoomID {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
// delete roomid from player
|
||||||
|
if err := cm.repo.PlayerExitRoom(ctx, player.Username); err != nil {
|
||||||
|
cm.log.Error("failed to unset room", "err", err)
|
||||||
|
if err := tx.Rollback(); err != nil {
|
||||||
|
cm.log.Error("failed to rollback transaction for actions cleanup", "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := tx.Commit(); err != nil {
|
||||||
|
cm.log.Error("failed to commit transaction for actions cleanup", "err", err)
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@ type PlayersRepo interface {
|
|||||||
PlayerExitRoom(ctx context.Context, username string) error
|
PlayerExitRoom(ctx context.Context, username string) error
|
||||||
PlayerListNames(ctx context.Context) ([]string, error)
|
PlayerListNames(ctx context.Context) ([]string, error)
|
||||||
PlayerList(ctx context.Context, isBot bool) ([]models.Player, error)
|
PlayerList(ctx context.Context, isBot bool) ([]models.Player, error)
|
||||||
|
PlayerListAll(ctx context.Context) ([]models.Player, error)
|
||||||
PlayerListByRoom(ctx context.Context, roomID string) ([]models.Player, error)
|
PlayerListByRoom(ctx context.Context, roomID string) ([]models.Player, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +96,16 @@ func (p *RepoProvider) PlayerList(ctx context.Context, isBot bool) ([]models.Pla
|
|||||||
return players, nil
|
return players, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) PlayerListAll(ctx context.Context) ([]models.Player, error) {
|
||||||
|
var players []models.Player
|
||||||
|
query := "SELECT id, room_id, username, team, role, is_bot FROM players;"
|
||||||
|
err := sqlx.SelectContext(ctx, p.DB, &players, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return players, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *RepoProvider) PlayerListByRoom(ctx context.Context, roomID string) ([]models.Player, error) {
|
func (p *RepoProvider) PlayerListByRoom(ctx context.Context, roomID string) ([]models.Player, error) {
|
||||||
var players []models.Player
|
var players []models.Player
|
||||||
err := sqlx.SelectContext(ctx, p.DB, &players, "SELECT id, room_id, username, team, role, is_bot FROM players WHERE room_id = ?", roomID)
|
err := sqlx.SelectContext(ctx, p.DB, &players, "SELECT id, room_id, username, team, role, is_bot FROM players WHERE room_id = ?", roomID)
|
||||||
|
Reference in New Issue
Block a user