v0.1.35: устранены гонки map (ChangeVisibility/DeleteBatch) и nil-deref под Lock + OverLimit

This commit is contained in:
“Naeel”
2026-08-14 18:48:35 +04:00
parent 9cde807dda
commit c4da02c814
8 changed files with 74 additions and 44 deletions
+13 -10
View File
@@ -40,10 +40,6 @@ func DeleteMessageBatchV1(req *http.Request) (int, interfaces.AbstractResponseBo
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)
}
@@ -63,6 +59,13 @@ func DeleteMessageBatchV1(req *http.Request) (int, interfaces.AbstractResponseBo
models.SyncQueues.Lock()
defer models.SyncQueues.Unlock()
// Проверка существования очереди ВНУТРИ Lock: раньше была БЕЗ блокировки
// (чтение map) — concurrent map read/write при параллельном DeleteQueue.
queue, exists := models.SyncQueues.Queues[key]
if !exists {
return utils.CreateErrorResponseV1("QueueNotFound", true)
}
deleteMessageMap := make(map[string]*deleteEntry)
for _, entry := range requestBody.Entries {
deleteMessageMap[entry.ReceiptHandle] = &deleteEntry{
@@ -74,13 +77,13 @@ func DeleteMessageBatchV1(req *http.Request) (int, interfaces.AbstractResponseBo
deletedEntries := make([]models.DeleteMessageBatchResultEntry, 0)
deletedUuids := make([]string, 0)
remainingMessages := make([]models.SqsMessage, 0, len(models.SyncQueues.Queues[key].Messages))
remainingMessages := make([]models.SqsMessage, 0, len(queue.Messages))
for _, message := range models.SyncQueues.Queues[key].Messages {
for _, message := range queue.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)
queue.UnlockGroup(message.GroupID)
delete(queue.Duplicates, message.DeduplicationID)
de.Deleted = true
deletedEntries = append(deletedEntries, models.DeleteMessageBatchResultEntry{Id: de.Id})
deletedUuids = append(deletedUuids, message.Uuid)
@@ -89,11 +92,11 @@ func DeleteMessageBatchV1(req *http.Request) (int, interfaces.AbstractResponseBo
}
}
models.SyncQueues.Queues[key].Messages = remainingMessages
queue.Messages = remainingMessages
// Удаляем сообщения из Redis отдельно — O(batch_size)
persistence.DeleteMessagesPersist(key, deletedUuids)
// Метаданные очереди (duplicates, FIFO state)
persistence.SaveQueue(key, models.SyncQueues.Queues[key])
persistence.SaveQueue(key, queue)
notFoundEntries := make([]models.BatchResultErrorEntry, 0)
for _, de := range deleteMessageMap {