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
+21 -7
View File
@@ -129,22 +129,36 @@ func SendMessageV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
msg.DelaySecs = delaySecs
models.SyncQueues.Lock()
fifoSeqNumber := ""
if models.SyncQueues.Queues[key].IsFIFO {
fifoSeqNumber = models.SyncQueues.Queues[key].NextSequenceNumber(messageGroupID)
// Перепроверка под Lock: очередь могла быть удалена между RLock-проверкой
// выше и захватом Lock (иначе nil-pointer deref).
queue = models.SyncQueues.Queues[key]
if queue == nil {
models.SyncQueues.Unlock()
return utils.CreateErrorResponseV1("QueueNotFound", true)
}
// Повторная проверка лимита под Lock: между RLock-снимком и захватом Lock
// другие горутины могли добавить сообщения (мягкий OOM-лимит).
if len(queue.Messages) >= MaxMessagesForQueue(queue.IsFIFO) {
models.SyncQueues.Unlock()
return utils.CreateErrorResponseV1("OverLimit", true)
}
if !models.SyncQueues.Queues[key].IsDuplicate(messageDeduplicationID) {
models.SyncQueues.Queues[key].Messages = append(models.SyncQueues.Queues[key].Messages, msg)
fifoSeqNumber := ""
if queue.IsFIFO {
fifoSeqNumber = queue.NextSequenceNumber(messageGroupID)
}
if !queue.IsDuplicate(messageDeduplicationID) {
queue.Messages = append(queue.Messages, msg)
// Персистим одно сообщение отдельно — O(msg_size) вместо O(N*msg_size)
persistence.SaveMessage(key, &msg)
} else {
log.Debugf("Duplicate message deduplicationId [%s] in queue [%s]", messageDeduplicationID, queueName)
}
models.SyncQueues.Queues[key].InitDuplicatation(messageDeduplicationID)
queue.InitDuplicatation(messageDeduplicationID)
// Сохраняем метаданные очереди (FIFO state, duplicates) — без Messages
persistence.SaveQueue(key, models.SyncQueues.Queues[key])
persistence.SaveQueue(key, queue)
models.SyncQueues.Unlock()
// Логируем только метаданные — тело сообщения не логируется (perf + security)
log.Infof("Queue: %s, MessageId: %s, Size: %d bytes", queueName, msg.Uuid, len(messageBody))