gosqs: запретить self/cyclic RedrivePolicy (иначе deadlock при переносе в DLQ)

This commit is contained in:
Repinoid
2026-10-11 08:34:01 +03:00
parent b179ec6de7
commit e720f1ffcb
+15
View File
@@ -84,6 +84,21 @@ func setQueueAttributesV1(q *models.Queue, attr models.QueueAttributes, provided
log.Error("Invalid RedrivePolicy Attribute")
return fmt.Errorf("InvalidAttributeValue")
}
// Запрет self-DLQ (q → q) и циклов (A → B → A): при переносе в DLQ
// переносящий код берёт DeadLetterQueue.LockMu() под уже взятым q.mu —
// self/цикл даёт немедленный self-deadlock (или AB/BA-deadlock).
if deadLetterQueue == q {
log.Error("Invalid RedrivePolicy Attribute: self DLQ")
return fmt.Errorf("InvalidAttributeValue")
}
// Обход цепочки DLQ для детекта циклов. Лимит 100 — защита от уже
// существующего в данных цикла (если бы он там был).
for cur, steps := deadLetterQueue, 0; cur != nil && steps < 100; cur, steps = cur.DeadLetterQueue, steps+1 {
if cur == q {
log.Error("Invalid RedrivePolicy Attribute: cyclic DLQ")
return fmt.Errorf("InvalidAttributeValue")
}
}
q.DeadLetterQueue = deadLetterQueue
q.MaxReceiveCount = attr.RedrivePolicy.MaxReceiveCount.Int()
}