v0.1.35: query-mode XML-ответы, TOCTOU receive, валидации AWS, purge 60s, сужение локов
This commit is contained in:
+41
-9
@@ -63,38 +63,66 @@ type Queue struct {
|
||||
EnableDuplicates bool
|
||||
Duplicates map[string]time.Time
|
||||
Tags map[string]string
|
||||
// LastPurgeTime — время последнего успешного PurgeQueue.
|
||||
// Используется для запрета повторного purge ранее чем через 60 секунд
|
||||
// (требование AWS: PurgeQueueInProgress). Нулевое значение = purge ещё не выполнялся.
|
||||
LastPurgeTime time.Time
|
||||
}
|
||||
|
||||
// NextSequenceNumber — возвращает следующий порядковый номер сообщения FIFO-группы.
|
||||
//
|
||||
// Логическая схема: каждый вызов инкрементирует счётчик группы и возвращает
|
||||
// его строковое представление (порядковые номера в FIFO должны расти монотонно).
|
||||
//
|
||||
// ВАЖНО (фикс): раньше при ПЕРВОМ обращении к группе map пересоздавалась целиком
|
||||
// (q.FIFOSequenceNumbers = map[string]int{groupId: 0}) — счётчики ВСЕХ остальных
|
||||
// групп терялись, и порядковые номера начинали дублироваться. Теперь map только
|
||||
// инициализируется один раз (если nil), а счётчик конкретной группы инкрементируется.
|
||||
func (q *Queue) NextSequenceNumber(groupId string) string {
|
||||
if _, ok := q.FIFOSequenceNumbers[groupId]; !ok {
|
||||
q.FIFOSequenceNumbers = map[string]int{
|
||||
groupId: 0,
|
||||
}
|
||||
if q.FIFOSequenceNumbers == nil {
|
||||
q.FIFOSequenceNumbers = make(map[string]int)
|
||||
}
|
||||
|
||||
q.FIFOSequenceNumbers[groupId]++
|
||||
return strconv.Itoa(q.FIFOSequenceNumbers[groupId])
|
||||
}
|
||||
|
||||
// IsLocked — проверяет, заблокирована ли FIFO-группа.
|
||||
// Группа блокируется при выдаче её сообщения в ReceiveMessage и остаётся
|
||||
// заблокированной, пока сообщение in-flight (до DeleteMessage или таймаута
|
||||
// видимости) — это гарантирует порядок обработки внутри группы.
|
||||
func (q *Queue) IsLocked(groupId string) bool {
|
||||
_, ok := q.FIFOMessages[groupId]
|
||||
return ok
|
||||
}
|
||||
|
||||
// LockGroup — блокирует FIFO-группу (помечает как занятую).
|
||||
//
|
||||
// ВАЖНО (фикс): раньше при ПЕРВОМ обращении map пересоздавалась целиком
|
||||
// (q.FIFOMessages = map[string]int{groupId: 0}) — блокировки ВСЕХ остальных
|
||||
// групп терялись, и их сообщения могли выдаваться одновременно. Теперь map
|
||||
// только инициализируется один раз, а для группы проставляется ключ.
|
||||
func (q *Queue) LockGroup(groupId string) {
|
||||
if _, ok := q.FIFOMessages[groupId]; !ok {
|
||||
q.FIFOMessages = map[string]int{
|
||||
groupId: 0,
|
||||
}
|
||||
if q.FIFOMessages == nil {
|
||||
q.FIFOMessages = make(map[string]int)
|
||||
}
|
||||
q.FIFOMessages[groupId] = 0
|
||||
}
|
||||
|
||||
// UnlockGroup — снимает блокировку FIFO-группы.
|
||||
// Вызывается после удаления сообщения или при истечении таймаута видимости
|
||||
// (см. PeriodicTasks → processQueueTick).
|
||||
func (q *Queue) UnlockGroup(groupId string) {
|
||||
if _, ok := q.FIFOMessages[groupId]; ok {
|
||||
delete(q.FIFOMessages, groupId)
|
||||
}
|
||||
}
|
||||
|
||||
// IsDuplicate — проверяет, было ли сообщение с таким deduplicationId уже
|
||||
// добавлено в очередь в пределах deduplication-окна.
|
||||
//
|
||||
// Логическая схема: дубликаты отслеживаются ТОЛЬКО для FIFO-очередей с
|
||||
// включённой дупликацией (EnableDuplicates) и непустым deduplicationId.
|
||||
// Для остальных случаев дубликаты не отслеживаются (AWS-семантика).
|
||||
func (q *Queue) IsDuplicate(deduplicationId string) bool {
|
||||
if !q.EnableDuplicates || !q.IsFIFO || deduplicationId == "" {
|
||||
return false
|
||||
@@ -105,6 +133,10 @@ func (q *Queue) IsDuplicate(deduplicationId string) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
// InitDuplicatation — регистрирует deduplicationId с текущим временем.
|
||||
// Эта отметка — начало deduplication-окна; просроченные записи удаляются
|
||||
// фоновой задачей PeriodicTasks (deduplication period expired).
|
||||
// Для не-FIFO очередей или пустого deduplicationId — no-op.
|
||||
func (q *Queue) InitDuplicatation(deduplicationId string) {
|
||||
if !q.EnableDuplicates || !q.IsFIFO || deduplicationId == "" {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user