From 5284a56f7aade0b7f0ff30360ef2ac6136fa6c05 Mon Sep 17 00:00:00 2001 From: Repinoid Date: Sun, 11 Oct 2026 08:54:21 +0300 Subject: [PATCH] =?UTF-8?q?SQS:=20delete=20batch=20=D0=BA=D0=BB=D1=8E?= =?UTF-8?q?=D1=87=20=D0=BF=D0=BE=20Id,=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20DelaySeconds=200-900?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/gosqs/delete_message_batch.go | 20 ++++++++++++++------ app/gosqs/send_message.go | 3 +++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/gosqs/delete_message_batch.go b/app/gosqs/delete_message_batch.go index 9c0a223..64af928 100644 --- a/app/gosqs/delete_message_batch.go +++ b/app/gosqs/delete_message_batch.go @@ -68,13 +68,19 @@ func DeleteMessageBatchV1(req *http.Request) (int, interfaces.AbstractResponseBo } defer queue.UnlockMu() - deleteMessageMap := make(map[string]*deleteEntry) + // Ключ — Id, а НЕ ReceiptHandle: два entry с одинаковым ReceiptHandle и разными + // Id не должны перезаписывать друг друга (первый исчезал бы и не попадал ни в + // Successful, ни в Failed — ревью 2026-10-11). entriesByHandle — обратный индекс. + entriesByID := make(map[string]*deleteEntry) + entriesByHandle := make(map[string][]*deleteEntry) for _, entry := range requestBody.Entries { - deleteMessageMap[entry.ReceiptHandle] = &deleteEntry{ + de := &deleteEntry{ Id: entry.Id, ReceiptHandle: entry.ReceiptHandle, Deleted: false, } + entriesByID[entry.Id] = de + entriesByHandle[entry.ReceiptHandle] = append(entriesByHandle[entry.ReceiptHandle], de) } deletedEntries := make([]models.DeleteMessageBatchResultEntry, 0) @@ -87,7 +93,7 @@ func DeleteMessageBatchV1(req *http.Request) (int, interfaces.AbstractResponseBo continue } message := &queue.Messages[i] - de, found := deleteMessageMap[message.ReceiptHandle] + des, found := entriesByHandle[message.ReceiptHandle] if !found { continue } @@ -97,8 +103,10 @@ func DeleteMessageBatchV1(req *http.Request) (int, interfaces.AbstractResponseBo queue.ClearInFlight(i, message.ReceiptHandle) queue.UnlockGroup(groupID) // Duplicates НЕ чистим — dedup-окно 5 минут живёт независимо от удаления (AWS). - de.Deleted = true - deletedEntries = append(deletedEntries, models.DeleteMessageBatchResultEntry{Id: de.Id}) + for _, de := range des { + de.Deleted = true + deletedEntries = append(deletedEntries, models.DeleteMessageBatchResultEntry{Id: de.Id}) + } deletedUuids = append(deletedUuids, uuid) queue.RemoveIndex(i) } @@ -108,7 +116,7 @@ func DeleteMessageBatchV1(req *http.Request) (int, interfaces.AbstractResponseBo persistence.SaveQueue(key, queue) notFoundEntries := make([]models.BatchResultErrorEntry, 0) - for _, de := range deleteMessageMap { + for _, de := range entriesByID { if !de.Deleted { notFoundEntries = append(notFoundEntries, models.BatchResultErrorEntry{ Code: "1", diff --git a/app/gosqs/send_message.go b/app/gosqs/send_message.go index d9fb63b..77071c6 100644 --- a/app/gosqs/send_message.go +++ b/app/gosqs/send_message.go @@ -117,6 +117,9 @@ func SendMessageV1(req *http.Request) (int, interfaces.AbstractResponseBody) { return utils.CreateErrorResponseV1("OverLimit", true) } + if requestBody.DelaySeconds < 0 || requestBody.DelaySeconds > 900 { + return utils.CreateErrorResponseV1("InvalidParameterValue", true) + } if requestBody.DelaySeconds != 0 { delaySecs = requestBody.DelaySeconds }