// Изменено: 2026-04-09 // DeleteMessageBatchV1 — пакетное удаление сообщений из очереди тенанта. package gosqs import ( "net/http" "strings" "shared-sqs/app/interfaces" "shared-sqs/app/models" "shared-sqs/app/utils" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" ) func DeleteMessageBatchV1(req *http.Request) (int, interfaces.AbstractResponseBody) { requestBody := models.NewDeleteMessageBatchRequest() ok := utils.REQUEST_TRANSFORMER(requestBody, req, false) if !ok { log.Error("Invalid Request - DeleteMessageBatchV1") return utils.CreateErrorResponseV1("InvalidParameterValue", true) } t := getTenantFromContext(req) if t == nil { return utils.CreateErrorResponseV1("InvalidClientTokenId", true) } queueUrl := requestBody.QueueUrl queueName := "" if queueUrl == "" { vars := mux.Vars(req) queueName = vars["queueName"] } else { uriSegments := strings.Split(queueUrl, "/") queueName = uriSegments[len(uriSegments)-1] } key := tenantQueueKey(t.AccessKey, queueName) if _, ok := models.SyncQueues.Queues[key]; !ok { return utils.CreateErrorResponseV1("QueueNotFound", true) } if len(requestBody.Entries) == 0 { return utils.CreateErrorResponseV1("EmptyBatchRequest", true) } if len(requestBody.Entries) > 10 { return utils.CreateErrorResponseV1("TooManyEntriesInBatchRequest", true) } ids := map[string]bool{} for _, v := range requestBody.Entries { if _, found := ids[v.Id]; found { return utils.CreateErrorResponseV1("BatchEntryIdsNotDistinct", true) } ids[v.Id] = true } models.SyncQueues.Lock() defer models.SyncQueues.Unlock() deleteMessageMap := make(map[string]*deleteEntry) for _, entry := range requestBody.Entries { deleteMessageMap[entry.ReceiptHandle] = &deleteEntry{ Id: entry.Id, ReceiptHandle: entry.ReceiptHandle, Deleted: false, } } deletedEntries := make([]models.DeleteMessageBatchResultEntry, 0) remainingMessages := make([]models.SqsMessage, 0, len(models.SyncQueues.Queues[key].Messages)) for _, message := range models.SyncQueues.Queues[key].Messages { if de, found := deleteMessageMap[message.ReceiptHandle]; found { log.Debugf("FIFO Queue %s unlocking group %s:", queueName, message.GroupID) models.SyncQueues.Queues[key].UnlockGroup(message.GroupID) delete(models.SyncQueues.Queues[key].Duplicates, message.DeduplicationID) de.Deleted = true deletedEntries = append(deletedEntries, models.DeleteMessageBatchResultEntry{Id: de.Id}) } else { remainingMessages = append(remainingMessages, message) } } models.SyncQueues.Queues[key].Messages = remainingMessages notFoundEntries := make([]models.BatchResultErrorEntry, 0) for _, de := range deleteMessageMap { if !de.Deleted { notFoundEntries = append(notFoundEntries, models.BatchResultErrorEntry{ Code: "1", Id: de.Id, Message: "Message not found", SenderFault: true, }) } } respStruct := models.DeleteMessageBatchResponse{ Xmlns: models.BaseXmlns, Result: models.DeleteMessageBatchResult{ Successful: deletedEntries, Failed: notFoundEntries, }, Metadata: models.BaseResponseMetadata, } return http.StatusOK, respStruct } type deleteEntry struct { Id string ReceiptHandle string Error string Deleted bool }