fix(concurrency,durability): address Opus review critical findings
- create_queue: SaveQueue under per-queue lock, not global SyncQueues.Lock (fixes fatal concurrent map iteration/write on idempotent CreateQueue of existing FIFO queue) - delete_message_batch: reject empty ReceiptHandle (JSON protocol bypass deleted all unreceived msgs) - send_message/send_message_batch: register dedupId only after successful persist (retry with same dedupId no longer returns 200 without persisting) - memory_guard: global HeapAlloc guard (SHARED_SQS_MAX_HEAP_MB, 0=off) in send paths
This commit is contained in:
@@ -71,7 +71,8 @@ func CreateQueueV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
|
||||
}
|
||||
|
||||
models.SyncQueues.Lock()
|
||||
if _, exists := models.SyncQueues.Queues[key]; !exists {
|
||||
existing, exists := models.SyncQueues.Queues[key]
|
||||
if !exists {
|
||||
// Проверка лимита очередей тенанта
|
||||
if t.MaxQueues > 0 && countTenantQueues(t.AccessKey) >= t.MaxQueues {
|
||||
models.SyncQueues.Unlock()
|
||||
@@ -79,10 +80,18 @@ func CreateQueueV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
|
||||
}
|
||||
log.Infof("Creating Queue: %s (tenant: %s)", queueName, t.ID)
|
||||
models.SyncQueues.AddQueue(key, queue)
|
||||
existing = queue
|
||||
}
|
||||
// Сохраняем очередь в Redis пока держим Lock — консистентный снапшот
|
||||
persistence.SaveQueue(key, models.SyncQueues.Queues[key])
|
||||
models.SyncQueues.Unlock()
|
||||
|
||||
// SaveQueue маршалит map'ы очереди (Duplicates/FIFO*/Tags) в JSON. Это нужно
|
||||
// делать под per-queue блокировкой, а НЕ под глобальным SyncQueues.Lock:
|
||||
// мутаторы (send/tag/CMV) пишут в эти map под queue.mu, и идемпотентный
|
||||
// CreateQueue существующей очереди без queue.mu даёт fatal
|
||||
// "concurrent map iteration and map write" (краш всего процесса).
|
||||
existing.LockMu()
|
||||
persistence.SaveQueue(key, existing)
|
||||
existing.UnlockMu()
|
||||
respStruct := models.CreateQueueResponse{
|
||||
Xmlns: models.BaseXmlns,
|
||||
Result: models.CreateQueueResult{QueueUrl: queueUrl},
|
||||
|
||||
Reference in New Issue
Block a user