P1.1: per-queue блокировки вместо глобального лока на операции с очередью

Все операции с содержимым очереди (send/receive/delete/visibility/purge/attributes/
tags/admin/gauge/tick) переведены на per-queue RWMutex (QueueStore.GetLocked/
GetRLocked + queue.LockMu). Глобальный SyncQueues-лок остался только для map и
неизменяемых полей. DLQ-переносы берут лок DLQ отдельно (порядок main→DLQ).
marshalQueueMeta больше не мутирует очередь (DTO-снапшот). Устранён дедлок
create_queue (setQueueAttributesV1 вызывается вне глобального лока). Добавлены
конкурентные тесты; go test -race зелёный. Снимает боттлнек: синхронный Redis-I/O
больше не держит глобальный лок.
This commit is contained in:
Repinoid
2026-10-06 18:58:16 +03:00
parent ed17c6cbd0
commit fd8ffc329d
21 changed files with 252 additions and 181 deletions
+3 -4
View File
@@ -45,13 +45,12 @@ func SetQueueAttributesV1(req *http.Request) (int, interfaces.AbstractResponseBo
key := tenantQueueKey(t.AccessKey, queueName)
log.Infof("Set Queue Attributes: %s (tenant: %s)", queueName, t.ID)
models.SyncQueues.Lock()
defer models.SyncQueues.Unlock()
queue, ok := models.SyncQueues.Queues[key]
if !ok {
queue := models.SyncQueues.GetLocked(key)
if queue == nil {
log.Warningf("Set Queue Attributes: %s, queue does not exist for tenant %s", queueName, t.ID)
return utils.CreateErrorResponseV1("QueueNotFound", true)
}
defer queue.UnlockMu()
// Список имён переданных атрибутов — для whitelist-валидации.
// Query-протокол: имена видны в form (Attribute.N.Name).
// JSON-протокол: структура уже разобрана из тела, список имён недоступен → nil