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")
|
log.Error("Invalid RedrivePolicy Attribute")
|
||||||
return fmt.Errorf("InvalidAttributeValue")
|
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.DeadLetterQueue = deadLetterQueue
|
||||||
q.MaxReceiveCount = attr.RedrivePolicy.MaxReceiveCount.Int()
|
q.MaxReceiveCount = attr.RedrivePolicy.MaxReceiveCount.Int()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user