Проблема
Content не ограничен по размеру ни в Dex.Cap.Outbox, ни в Dex.Cap.Inbox. В обоих пакетах есть только null-check, EF-конфигурация не задаёт HasMaxLength — колонка ложится в PostgreSQL как text, то есть до 1 ГБ на строку.
Проверено на текущем main: rg 'HasMaxLength|MaxLength' по Dex.Cap.Outbox, Dex.Cap.Outbox.Ef, Dex.Cap.Inbox, Dex.Cap.Inbox.Ef не находит ничего. Для сравнения, MessageId и ConsumerId в Inbox лимитированы 256.
Это не дефект конкретного PR — Inbox повторил конвенцию Outbox. Поэтому чинить надо симметрично в обоих пакетах, иначе конвенция разъедется.
Почему это важнее для Inbox
Асимметрия рисков между пакетами:
|
Outbox |
Inbox |
Кто пишет Content |
свой код сервиса |
внешний источник |
| Сколько живёт после успеха |
до уборки, тип может требовать немедленного удаления |
весь retention (дефолт 30 дней) |
В Inbox тело приходит с чужой стороны и лежит месяц. Один источник, отправивший аномально большой payload, раздувает таблицу, замедляет захват (лишние страницы в heap) и попадает в бэкап.
Предлагаемое решение
Опция с дефолтом, не жёсткий HasMaxLength:
- лимит задаётся опцией (
MaxContentLength или аналог) с разумным дефолтом, одинаково в OutboxOptions и InboxOptions;
- проверка на приёме — в
EnqueueAsync (Inbox) и на постановке в Outbox, с внятным исключением, а не отказом БД на вставке;
- дефолт выбрать так, чтобы существующие потребители не сломались; при превышении — ошибка на входе, где есть контекст, а не глубоко в EF.
Жёсткий HasMaxLength навязал бы политику всем потребителям и потребовал бы миграции существующих таблиц — поэтому опция.
Контекст
Найдено при ревью #230 (Dex.Cap.Inbox, SUP-1085). В PR #230 не правим сознательно: это общая конвенция обоих пакетов, а не регрессия PR.
Проблема
Contentне ограничен по размеру ни вDex.Cap.Outbox, ни вDex.Cap.Inbox. В обоих пакетах есть только null-check, EF-конфигурация не задаётHasMaxLength— колонка ложится в PostgreSQL какtext, то есть до 1 ГБ на строку.Проверено на текущем
main:rg 'HasMaxLength|MaxLength'поDex.Cap.Outbox,Dex.Cap.Outbox.Ef,Dex.Cap.Inbox,Dex.Cap.Inbox.Efне находит ничего. Для сравнения,MessageIdиConsumerIdв Inbox лимитированы 256.Это не дефект конкретного PR — Inbox повторил конвенцию Outbox. Поэтому чинить надо симметрично в обоих пакетах, иначе конвенция разъедется.
Почему это важнее для Inbox
Асимметрия рисков между пакетами:
ContentВ Inbox тело приходит с чужой стороны и лежит месяц. Один источник, отправивший аномально большой payload, раздувает таблицу, замедляет захват (лишние страницы в heap) и попадает в бэкап.
Предлагаемое решение
Опция с дефолтом, не жёсткий
HasMaxLength:MaxContentLengthили аналог) с разумным дефолтом, одинаково вOutboxOptionsиInboxOptions;EnqueueAsync(Inbox) и на постановке в Outbox, с внятным исключением, а не отказом БД на вставке;Жёсткий
HasMaxLengthнавязал бы политику всем потребителям и потребовал бы миграции существующих таблиц — поэтому опция.Контекст
Найдено при ревью #230 (
Dex.Cap.Inbox, SUP-1085). В PR #230 не правим сознательно: это общая конвенция обоих пакетов, а не регрессия PR.