gosqs: запретить self/cyclic RedrivePolicy (иначе deadlock при переносе в DLQ)
This commit is contained in:
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user