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