From 00cbd78a9f822798b3006c037993f7ec3201b981 Mon Sep 17 00:00:00 2001 From: D3V1L Date: Tue, 18 Feb 2025 18:00:59 +0400 Subject: [PATCH 1/2] Prevent 2 users from being able to close a ticket at the same time --- bot/logic/close.go | 14 ++++++++++++++ bot/redis/openlock.go | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/bot/logic/close.go b/bot/logic/close.go index c6efd7a..145c120 100644 --- a/bot/logic/close.go +++ b/bot/logic/close.go @@ -40,6 +40,20 @@ func CloseTicket(ctx context.Context, cmd registry.CommandContext, reason *strin return } + // prevent duplicate ticket close + lock, err := redis.TakeTicketCloseLock(ctx, uint64(ticket.Id)) + if err != nil { + cmd.HandleError(err) + return + } + + defer func() { + _, unlockErr := lock.UnlockContext(ctx) + if unlockErr != nil { + sentry.ErrorWithContext(unlockErr, cmd.ToErrorContext()) + } + }() + defer func() { if !success { if err := dbclient.Client.AutoCloseExclude.Exclude(ctx, ticket.GuildId, ticket.Id); err != nil { diff --git a/bot/redis/openlock.go b/bot/redis/openlock.go index 7b83b74..db41909 100644 --- a/bot/redis/openlock.go +++ b/bot/redis/openlock.go @@ -24,3 +24,11 @@ func TakeTicketOpenLock(ctx context.Context, guildId uint64) (Mutex, error) { return mu, nil } + +func TakeTicketCloseLock(ctx context.Context, ticketId uint64) (Mutex, error) { + mu := rs.NewMutex(fmt.Sprintf("tickets:closelock:%d", ticketId), redsync.WithExpiry(TicketOpenLockExpiry)) + if err := mu.LockContext(ctx); err != nil { + return nil, err + } + return mu, nil +} From 1577637dd7bc8a69c56271bd8401b291570f68a8 Mon Sep 17 00:00:00 2001 From: D3V1L Date: Wed, 19 Feb 2025 08:22:31 +0400 Subject: [PATCH 2/2] Prevent 2 users from being able to close a ticket at the same time --- bot/logic/close.go | 1 - 1 file changed, 1 deletion(-) diff --git a/bot/logic/close.go b/bot/logic/close.go index 145c120..f65a0a4 100644 --- a/bot/logic/close.go +++ b/bot/logic/close.go @@ -40,7 +40,6 @@ func CloseTicket(ctx context.Context, cmd registry.CommandContext, reason *strin return } - // prevent duplicate ticket close lock, err := redis.TakeTicketCloseLock(ctx, uint64(ticket.Id)) if err != nil { cmd.HandleError(err)