fix(P1.2-revue): батч-видимость не заводила в DLQ + TOCTOU лимит в SendMessageBatch

1. ChangeMessageVisibilityBatch при VisibilityTimeout=0 лишь инкрементировал
   Retry и НЕ переносил сообщение в DLQ (логика была только в одиночной версии).
   Вынесен единый метод Queue.ResetVisibilityAndTryDLQ — сброс видимости +
   DLQ-перенос. Обе версии привели к одному пути.
2. SendMessageBatch: проверка OOM-лимита была только по устаревшему снимку
   (RLock → Lock) — добавлена повторная проверка под per-queue Lock (TOCTOU).
3. Инварианты InFlightIndexes/ensureIndexes зафиксированы в док-комментариях.

Тест: TestChangeVisibilityBatch_MovesToDLQ (падает на старой логике, зелёный
на новой).
This commit is contained in:
Repinoid
2026-10-07 08:35:52 +03:00
parent f96649b14e
commit 2e1c594892
4 changed files with 67 additions and 34 deletions
+8
View File
@@ -104,6 +104,14 @@ func SendMessageBatchV1(req *http.Request) (int, interfaces.AbstractResponseBody
queue.LockMu()
defer queue.UnlockMu()
// Повторная проверка лимита под per-queue Lock: снимок currentMsgCount выше
// был сделан под RLock, между ним и взятием Lock очередь могла измениться
// (гонка TOCTOU). Здесь — обязательная проверка по свежему числу живых.
if queue.LiveCount()+len(sendEntries) > MaxMessagesForQueue(queue.IsFIFO) {
return utils.CreateErrorResponseV1("OverLimit", true)
}
newMsgs := make([]models.SqsMessage, 0, len(sendEntries))
for _, sendEntry := range sendEntries {
msg := models.SqsMessage{MessageBody: sendEntry.MessageBody}