From 4e648f690e3fe84ec297e7b305a4c02587bbdc2f Mon Sep 17 00:00:00 2001 From: Repinoid Date: Sun, 11 Oct 2026 09:19:50 +0300 Subject: [PATCH] =?UTF-8?q?docs(history):=20=D0=B7=D0=B0=D1=84=D0=B8=D0=BA?= =?UTF-8?q?=D1=81=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20=D1=80=D0=B5?= =?UTF-8?q?=D1=88=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BE=20=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC=20=D0=BF?= =?UTF-8?q?=D1=83=D0=BD=D0=BA=D1=82=D0=B0=D0=BC=20(34/37/28=3DA)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HISTORY/2026-10-11-session-log.md | 33 ++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/HISTORY/2026-10-11-session-log.md b/HISTORY/2026-10-11-session-log.md index a5adbc6..ba18520 100644 --- a/HISTORY/2026-10-11-session-log.md +++ b/HISTORY/2026-10-11-session-log.md @@ -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. Верификация