docs(history): зафиксировать решения по оставленным пунктам (34/37/28=A)

This commit is contained in:
Repinoid
2026-10-11 09:19:50 +03:00
parent b864cab5be
commit 4e648f690e
+22 -11
View File
@@ -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. Верификация