diff --git a/backend/cmd/util/clean_queued_tickets/main.go b/backend/cmd/util/clean_queued_tickets/main.go new file mode 100644 index 0000000..cc9c9ce --- /dev/null +++ b/backend/cmd/util/clean_queued_tickets/main.go @@ -0,0 +1,87 @@ +package main + +import ( + "context" + "fmt" + "sync" + "sync/atomic" + "time" + + "github.com/aritrosaha10/frasertickets/lib" + "github.com/aritrosaha10/frasertickets/models" + "github.com/aritrosaha10/frasertickets/util" + "github.com/joho/godotenv" + "github.com/rs/zerolog/log" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" +) + +func main() { + // Just assume we're running in dev + godotenv.Load(".env.development") + + // Create new auth & DB refs + lib.Auth = lib.CreateNewAuth() + lib.Datastore = lib.CreateNewDB() + lib.Datastore.Connect() + defer lib.Datastore.Disconnect() + + ctx := context.Background() + + // Start logging + util.ConfigureZeroLog() + + queuedTickets, err := models.GetAllQueuedTickets(ctx) + if err != nil { + log.Fatal().Err(err).Msg("could not fetch all queued tickets") + } + + startTime := time.Now() + var waitGroup sync.WaitGroup + var successfulDeletions atomic.Uint64 + var delayedDeletions atomic.Uint64 + var failedDeletions atomic.Uint64 + for _, queuedTicket := range queuedTickets { + waitGroup.Add(1) + // Check if ticket exists, if it does, delete old queued ticket + go func(queuedTicket models.QueuedTicket) { + defer waitGroup.Done() + + user, err := models.GetUserByKey(ctx, "student_number", queuedTicket.StudentNumber) + if err != nil { + if err == mongo.ErrNoDocuments { + log.Info().Err(err).Str("studentNumber", queuedTicket.StudentNumber).Msg("no user with given student # exists yet") + delayedDeletions.Add(1) + return + } + log.Warn().Err(err).Str("studentNumber", queuedTicket.StudentNumber).Msg("could not check if user with student # exists") + failedDeletions.Add(1) + return + } + + if ticketExists, err := models.CheckIfTicketExists(ctx, bson.M{"owner": user.ID, "event": queuedTicket.EventID}); err != nil { + log.Warn().Err(err).Any("queuedTicket", queuedTicket).Msg("could not check for ticket existing") + failedDeletions.Add(1) + return + } else if !ticketExists { + return + } + + if err = models.DeleteQueuedTicket(ctx, queuedTicket.ID); err != nil { + log.Warn().Err(err).Any("queuedTicket", queuedTicket).Msg("could not delete old queued ticket") + failedDeletions.Add(1) + return + } + log.Info().Any("queuedTicket", queuedTicket).Msg("deleted old queued ticket") + successfulDeletions.Add(1) + }(queuedTicket) + } + + waitGroup.Wait() + endTime := time.Now() + + fmt.Printf("successfully created tickets in %d ms\n", endTime.Sub(startTime).Milliseconds()) + fmt.Printf("successful ticket deletions: %d\n", successfulDeletions.Load()) + fmt.Printf("delayed ticket deletions: %d\n", delayedDeletions.Load()) + fmt.Printf("failed ticket deletions: %d\n", failedDeletions.Load()) +} diff --git a/backend/models/queuedticket.go b/backend/models/queuedticket.go index f130e89..86c4f74 100644 --- a/backend/models/queuedticket.go +++ b/backend/models/queuedticket.go @@ -48,6 +48,22 @@ func CreateQueuedTicketIndices(ctx context.Context) error { return err } +func GetAllQueuedTickets(ctx context.Context) ([]QueuedTicket, error) { + cursor, err := lib.Datastore.Db.Collection(queuedTicketsColName).Find(ctx, bson.M{}) + if err != nil { + return []QueuedTicket{}, err + } + defer cursor.Close(ctx) + + // Attempt to decode BSON into structs + var queuedTickets []QueuedTicket + if err := cursor.All(ctx, &queuedTickets); err != nil { + return []QueuedTicket{}, err + } + + return queuedTickets, nil +} + func GetQueuedTicket(ctx context.Context, queuedTicketID primitive.ObjectID) (QueuedTicket, error) { res := lib.Datastore.Db.Collection(queuedTicketsColName).FindOne(ctx, bson.M{"_id": queuedTicketID}) if res.Err() != nil {