docs(history): зафиксировать решения по оставленным пунктам (34/37/28=A)
This commit is contained in:
@@ -54,11 +54,15 @@
|
||||
| 🟢 | `app/utils/utils.go` | `SqsErrors[errKey]` без проверки → nil-deref на неизвестном ключе | `5d38118` |
|
||||
| (🟡 new) | `app/gosqs/create_queue.go` | Очередь из API получала `VisibilityTimeout=0` и пр. (дефолты не подставлялись) | `5d38118` |
|
||||
|
||||
### Осознанно НЕ менялось (решения владельца/архитектуры)
|
||||
### Осознанно НЕ менялось — РЕШЕНИЯ (2026-10-11)
|
||||
|
||||
- 🟡34 (атрибуты «0 = не передано») — не менять совместимость.
|
||||
- 🟡37 (дефолт `SHARED_SQS_MAX_HEAP_MB`) — число зависит от RAM ВМ, решает владелец.
|
||||
- 🟡28 (не держать `queue.mu` во время сетевых вызовов) — **не сделано**: см. п.4.
|
||||
- 🟡34 (атрибуты «0 = не передано»): **решение — не менять** совместимость.
|
||||
Различать «не передано» и явный 0 потребовало бы перевести `QueueAttributes`
|
||||
на указатели — ломает JSON-протокол и Terraform-drift. Явный 0 — редкий сценарий.
|
||||
- 🟡37 (дефолт `SHARED_SQS_MAX_HEAP_MB`): **решение — оставить выключенным (0)**.
|
||||
Безопасное число зависит от RAM конкретной ВМ и числа тенантов — выбор владельца,
|
||||
не хардкод в коде.
|
||||
- 🟡28 (сеть под `queue.mu`): **решение — оставить как есть (вариант A)**. См. п.4.
|
||||
|
||||
## 3. Уточнение выводов ревьюера
|
||||
|
||||
@@ -80,14 +84,21 @@
|
||||
`Duplicates` (🟡33) фактически не воспроизводился в текущем коде — но защита
|
||||
добавлена как дешёвая страховка.
|
||||
|
||||
## 4. Осталось (требует решения/отдельного захода)
|
||||
## 4. 🟡28 — РЕШЕНИЕ (2026-10-11)
|
||||
|
||||
- **🟡28** (`send_message.go:150`, `delete_message.go`, `gosqs.go`): синхронный
|
||||
`SaveMessageSync` (до 3 с) выполняется под `queue.mu`. Простой вынос сети за
|
||||
`mu` **вносит регрессию**: между `Unlock` и повторным `Lock` появляется окно,
|
||||
в котором два конкурентных `SendMessage` с одним `deduplicationId` оба пройдут
|
||||
`IsDuplicate` (дубль), либо при откате `dedup` теряется. Корректное решение
|
||||
требует более сложной синхронизации — отложено до отдельного захода.
|
||||
- **Проблема**: синхронный `SaveMessageSync` (до 3 с) выполняется под `queue.mu`
|
||||
(`send_message.go:150`, `delete_message.go`, `admin.go`). Медленный Redis блокирует
|
||||
всю очередь.
|
||||
- **Варианты**: A) оставить; B) укоротить таймаут Redis-записи; C) полный рефакторинг
|
||||
с per-message синхронизацией.
|
||||
- **Выбрано A — оставить.** Обоснование:
|
||||
1. in-memory ядро очередей — одиночка, блокировка `queue.mu` локальна (одна очередь).
|
||||
2. Синхронный персист под `mu` = гарантия «нет потери подтверждённого сообщения
|
||||
при крахе пода» — приоритет проекта (надёжность, а не масштабирование).
|
||||
3. Вынос сети за `mu` вносит окно между `Unlock`/`Lock`: два конкурентных
|
||||
`SendMessage` с одним `deduplicationId` оба пройдут `IsDuplicate` (дубль),
|
||||
либо при откате `dedup` теряется сообщение — хуже кратковременной блокировки.
|
||||
4. Redis-авария — глобальная: деградирует всё, 2–3 с на очередь не критично.
|
||||
- 🟡34/🟡37 — см. п.2.
|
||||
|
||||
## 5. Верификация
|
||||
|
||||
Reference in New Issue
Block a user