diff --git a/backend/handlers/http.go b/backend/handlers/http.go index 30fd1b1..f8bb80d 100644 --- a/backend/handlers/http.go +++ b/backend/handlers/http.go @@ -59,7 +59,7 @@ func DeleteRoom(c *gin.Context) { user, err := authenticateUser(c, deleteRoomRequest.UserID) if err != nil { if err == mongo.ErrNoDocuments { // user not found - c.JSON(http.StatusNotFound, gin.H{"error": "user not found"}) + c.JSON(http.StatusUnauthorized, gin.H{"error": "user not found"}) return } // db error @@ -103,7 +103,7 @@ func JoinRoom(c *gin.Context) { user, err := authenticateUser(c, joinRoomRequest.UserID) if err != nil { if err == mongo.ErrNoDocuments { // user not found - c.JSON(http.StatusNotFound, gin.H{"error": "user not found"}) + c.JSON(http.StatusUnauthorized, gin.H{"error": "user not found"}) return } // db error @@ -131,7 +131,7 @@ func LeaveRoom(c *gin.Context) { _, err := authenticateUser(c, leaveRoomRequest.UserID) if err != nil { if err == mongo.ErrNoDocuments { // user not found - c.JSON(http.StatusNotFound, gin.H{"error": "user not found"}) + c.JSON(http.StatusUnauthorized, gin.H{"error": "user not found"}) return } // db error @@ -159,7 +159,7 @@ func UpdateRoom(c *gin.Context) { _, err := authenticateUser(c, updateRoomRequest.UserID) if err != nil { if err == mongo.ErrNoDocuments { // user not found - c.JSON(http.StatusNotFound, gin.H{"error": "user not found"}) + c.JSON(http.StatusUnauthorized, gin.H{"error": "user not found"}) return } // db error diff --git a/backend/main.go b/backend/main.go index d03f6a6..5c1e66d 100644 --- a/backend/main.go +++ b/backend/main.go @@ -104,6 +104,7 @@ func main() { go services.RegisterRooms(ctx) go services.UnregisterRooms(ctx) + go services.ExpireRooms(ctx) sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) diff --git a/backend/services/goroutines.go b/backend/services/goroutines.go index a3d4364..e852e34 100644 --- a/backend/services/goroutines.go +++ b/backend/services/goroutines.go @@ -5,6 +5,7 @@ import ( "log" "goderpad/db" + "goderpad/utils" ) // RegisterRooms listens for rooms to be registered and adds them to the Hub (in-memory store) @@ -39,3 +40,39 @@ func UnregisterRooms(ctx context.Context) { } } } + +// ExpireRooms periodically checks for rooms that have been inactive for over a week and deletes them +func ExpireRooms(ctx context.Context) { + ticker := utils.CreateTicker(utils.HOUR) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + allRooms, err := db.GetAllRooms(ctx) + if err != nil { + log.Println("Failed to fetch rooms for expiration:", err) + continue + } + + now := utils.GetCurrentUnixTimestamp() + for _, room := range allRooms { + if now-room.LastUsed > int64(utils.WEEK) { + // we don't delete from Hub because if it's in memory, it's active + hub := GetHub() + if roomFromHub := hub.GetRoom(room.ID); roomFromHub != nil { + continue + } + err := db.DeleteRoomByID(ctx, room.ID) + if err != nil { + log.Println("Failed to delete expired room:", err) + } else { + log.Println("Expired room deleted:", room.ID) + } + } + } + case <-ctx.Done(): + return + } + } +} diff --git a/backend/services/room.go b/backend/services/room.go index 877bb48..c5a1117 100644 --- a/backend/services/room.go +++ b/backend/services/room.go @@ -10,7 +10,6 @@ import ( ) func CreateRoom(ctx context.Context, request models.CreateRoomRequest) (string, error) { - hub := GetHub() roomID := utils.GenerateUUID() room := &models.Room{ @@ -28,7 +27,6 @@ func CreateRoom(ctx context.Context, request models.CreateRoomRequest) (string, } // Owner won't be added right away -> only when they open the room (join), they will be added - hub.Register <- room return roomID, nil } diff --git a/backend/utils/time.go b/backend/utils/time.go index f10037f..25e02db 100644 --- a/backend/utils/time.go +++ b/backend/utils/time.go @@ -7,3 +7,10 @@ import ( func GetCurrentUnixTimestamp() int64 { return time.Now().Unix() } + +func CreateTicker(duration time.Duration) *time.Ticker { + return time.NewTicker(duration) +} + +const HOUR = 1 * time.Hour +const WEEK = 7 * 24 * HOUR