Feat: remove rooms with no action
This commit is contained in:
@ -2,6 +2,8 @@ package crons
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
"gralias/repos"
|
"gralias/repos"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"time"
|
"time"
|
||||||
@ -25,6 +27,7 @@ func (cm *CronManager) Start() {
|
|||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
cm.CleanupRooms()
|
cm.CleanupRooms()
|
||||||
cm.CleanupActions()
|
cm.CleanupActions()
|
||||||
|
cm.CleanupInactiveRooms()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -133,3 +136,51 @@ 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package repos
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"gralias/models"
|
"gralias/models"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
)
|
)
|
||||||
@ -13,6 +14,7 @@ type ActionsRepo interface {
|
|||||||
ActionGetLastClue(ctx context.Context, roomID string) (*models.Action, error)
|
ActionGetLastClue(ctx context.Context, roomID string) (*models.Action, error)
|
||||||
ActionDeleteByRoomID(ctx context.Context, roomID string) error
|
ActionDeleteByRoomID(ctx context.Context, roomID string) error
|
||||||
ActionDeleteOrphaned(ctx context.Context) error
|
ActionDeleteOrphaned(ctx context.Context) error
|
||||||
|
ActionGetLastTimeByRoomID(ctx context.Context, roomID string) (time.Time, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RepoProvider) ActionList(ctx context.Context, roomID string) ([]models.Action, error) {
|
func (p *RepoProvider) ActionList(ctx context.Context, roomID string) ([]models.Action, error) {
|
||||||
@ -26,10 +28,20 @@ func (p *RepoProvider) ActionList(ctx context.Context, roomID string) ([]models.
|
|||||||
|
|
||||||
func (p *RepoProvider) ActionCreate(ctx context.Context, a *models.Action) error {
|
func (p *RepoProvider) ActionCreate(ctx context.Context, a *models.Action) error {
|
||||||
db := getDB(ctx, p.DB)
|
db := getDB(ctx, p.DB)
|
||||||
_, err := db.ExecContext(ctx, `INSERT INTO actions (room_id, actor, actor_color, action_type, word, word_color, number_associated, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, a.RoomID, a.Actor, a.ActorColor, a.Action, a.Word, a.WordColor, a.Number, a.CreatedAt.UnixNano())
|
_, err := db.ExecContext(ctx, `INSERT INTO actions (room_id, actor, actor_color, action_type, word, word_color, number_associated, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, a.RoomID, a.Actor, a.ActorColor, a.Action, a.Word, a.WordColor, a.Number, time.Now())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *RepoProvider) ActionGetLastTimeByRoomID(ctx context.Context, roomID string) (time.Time, error) {
|
||||||
|
lastTime := time.Time{}
|
||||||
|
err := sqlx.GetContext(ctx, p.DB, &lastTime,
|
||||||
|
`SELECT created_at FROM actions WHERE room_id = ? ORDER BY created_at DESC LIMIT 1`, roomID)
|
||||||
|
if err != nil {
|
||||||
|
return lastTime, err
|
||||||
|
}
|
||||||
|
return lastTime, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *RepoProvider) ActionGetLastClue(ctx context.Context, roomID string) (*models.Action, error) {
|
func (p *RepoProvider) ActionGetLastClue(ctx context.Context, roomID string) (*models.Action, error) {
|
||||||
action := &models.Action{}
|
action := &models.Action{}
|
||||||
err := sqlx.GetContext(ctx, p.DB, action, `SELECT actor, actor_color, action_type, word, word_color, number_associated, created_at FROM actions WHERE room_id = ? AND action_type = 'gave_clue' ORDER BY created_at DESC LIMIT 1`, roomID)
|
err := sqlx.GetContext(ctx, p.DB, action, `SELECT actor, actor_color, action_type, word, word_color, number_associated, created_at FROM actions WHERE room_id = ? AND action_type = 'gave_clue' ORDER BY created_at DESC LIMIT 1`, roomID)
|
||||||
|
@ -14,33 +14,25 @@ type CardMarksRepo interface {
|
|||||||
CardMarksByRoomID(ctx context.Context, roomID string) ([]models.CardMark, error)
|
CardMarksByRoomID(ctx context.Context, roomID string) ([]models.CardMark, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type cardMarksRepo struct {
|
func (r *RepoProvider) CardMarksByCardID(ctx context.Context, cardID uint32) ([]models.CardMark, error) {
|
||||||
db *sqlx.DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCardMarksRepo(db *sqlx.DB) CardMarksRepo {
|
|
||||||
return &cardMarksRepo{db: db}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *cardMarksRepo) CardMarksByCardID(ctx context.Context, cardID uint32) ([]models.CardMark, error) {
|
|
||||||
var cardMarks []models.CardMark
|
var cardMarks []models.CardMark
|
||||||
err := sqlx.SelectContext(ctx, getDB(ctx, r.db), &cardMarks, "SELECT * FROM card_marks WHERE card_id = ?", cardID)
|
err := sqlx.SelectContext(ctx, getDB(ctx, r.DB), &cardMarks, "SELECT * FROM card_marks WHERE card_id = ?", cardID)
|
||||||
return cardMarks, err
|
return cardMarks, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *cardMarksRepo) CardMarksAdd(ctx context.Context, cm *models.CardMark) error {
|
func (r *RepoProvider) CardMarksAdd(ctx context.Context, cm *models.CardMark) error {
|
||||||
_, err := getDB(ctx, r.db).ExecContext(ctx, "INSERT INTO card_marks (card_id, username) VALUES (?, ?)", cm.CardID, cm.Username)
|
_, err := getDB(ctx, r.DB).ExecContext(ctx, "INSERT INTO card_marks (card_id, username) VALUES (?, ?)", cm.CardID, cm.Username)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *cardMarksRepo) CardMarksRemove(ctx context.Context, cardID uint32, username string) error {
|
func (r *RepoProvider) CardMarksRemove(ctx context.Context, cardID uint32, username string) error {
|
||||||
db := getDB(ctx, r.db)
|
db := getDB(ctx, r.DB)
|
||||||
_, err := db.ExecContext(ctx, "DELETE FROM card_marks WHERE card_id = ? AND username = ?", cardID, username)
|
_, err := db.ExecContext(ctx, "DELETE FROM card_marks WHERE card_id = ? AND username = ?", cardID, username)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *cardMarksRepo) CardMarksByRoomID(ctx context.Context, roomID string) ([]models.CardMark, error) {
|
func (r *RepoProvider) CardMarksByRoomID(ctx context.Context, roomID string) ([]models.CardMark, error) {
|
||||||
var cardMarks []models.CardMark
|
var cardMarks []models.CardMark
|
||||||
err := sqlx.SelectContext(ctx, getDB(ctx, r.db), &cardMarks, "SELECT * FROM card_marks WHERE card_id IN (select id from word_cards where room_id = ?)", roomID)
|
err := sqlx.SelectContext(ctx, getDB(ctx, r.DB), &cardMarks, "SELECT * FROM card_marks WHERE card_id IN (select id from word_cards where room_id = ?)", roomID)
|
||||||
return cardMarks, err
|
return cardMarks, err
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ type RepoProvider struct {
|
|||||||
DB *sqlx.DB
|
DB *sqlx.DB
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
pathToDB string
|
pathToDB string
|
||||||
CardMarksRepo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRepoProvider(pathToDB string) *RepoProvider {
|
func NewRepoProvider(pathToDB string) *RepoProvider {
|
||||||
@ -44,7 +43,6 @@ func NewRepoProvider(pathToDB string) *RepoProvider {
|
|||||||
rp := &RepoProvider{
|
rp := &RepoProvider{
|
||||||
DB: db,
|
DB: db,
|
||||||
pathToDB: pathToDB,
|
pathToDB: pathToDB,
|
||||||
CardMarksRepo: NewCardMarksRepo(db),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
go rp.pingLoop()
|
go rp.pingLoop()
|
||||||
|
Reference in New Issue
Block a user