- Очередью служит сама таблица: доставка ждёт свёртки в статусе `pending`, канал несёт только бит «есть работа». Переполнять нечего, падение процесса очередь не теряет, а подбор `pending` при старте — обычный проход воркера, а не отдельный код. Классификация исхода общая с пересборкой журнала. - Исход разбора начал отражать доставку, а не обстоятельства: отмена и занятость базы статус не меняют (иначе конкуренция за базу выводила бы доставку из очереди навсегда), паника свёртки больше не валит процесс, а учёт доставки идёт через транзакцию с повторами. - Длинный бюджет ответа выдан маршруту приёма, а не всему серверу: `write_timeout` в Go покрывает и чтение тела, и общий подъём снял бы защиту с остальных маршрутов.
9.1 KiB
MODIFIED Requirements
Requirement: Отчёт, оракул и исход команды
Система SHALL завершать пересборку отчётом, который несёт счётчики (проиграно, свёрнуто, отказов по классам, тел без учётной записи, строк без тела, пропущенных файлов, повторов, объектов до и после) и два отпечатка — рабочей витрины и пересобранной, — с прямым ответом, совпали они или нет.
Отказы SHALL считаться по классам: слой не выводится, содержимое не разбирается, работа отложена по обстоятельствам, всё прочее. Невыведенный слой есть в каждом журнале и штатен; общий счётчик отправлял бы человека искать дефект там, где его нет. Отдельно называть человеку следует только нештатные отказы.
Отложенная доставка (занятость базы, отмена работы снаружи) SHALL считаться нештатной для пересборки, хотя для фоновой свёртки она штатна: пересборка идёт в свежий файл при единственном писателе, и такая доставка в собранной витрине просто отсутствует — вместе с теми, кто наследовал от неё слой. Классы при этом общие с фоновой свёрткой: второй классификатор разошёлся бы с первым молча.
Число объектов «было и стало» SHALL печататься рядом с отпечатками: отпечатки отвечают «да/нет», а решение о подмене необратимо, и по «да/нет» нельзя судить о направлении расхождения. Именно пара чисел — 1737 против 1742 — поймала прошлый дефект наследования слоя.
Отпечаток здесь оракул, а не украшение: число объектов к правилу разрешения столкновений нечувствительно — на координате всегда ровно одна точка, и правило выбирает, какая, а не сколько. «Объектов столько же» совпало бы и при заведомо сломанном правиле.
Отпечаток рабочей витрины SHALL сниматься до начала проигрывания, а число доставок в рабочей базе — до и после. Ненулевая разница SHALL называться в отчёте, и при ней процедура подмены печататься MUST NOT: доставки, приехавшие за время прогона, есть в рабочей базе и в архиве, но не в собранном файле, и подмена стёрла бы их учёт вместе с заголовками, которых в архиве нет.
Величины, которые не снимались, отчёт печатать MUST NOT. При отмене отпечаток пересобранной витрины и число доставок после прогона не измеряются вовсе — печатать их сравнение значило бы выдать неизмеренное за измеренное, причём в единственном оракуле задачи. Ожидаемые классы расхождения (новые доставки за время прогона, непереносимый признак запечатанного часа, исправленный разбор) SHALL называться отдельно от самого факта расхождения.
Исход команды. Расхождение отпечатков отказом быть MUST NOT: после исправления разбора оно ожидаемо и есть сам смысл пересборки. Отказ отдельной доставки отказом команды тоже MUST NOT быть: доставка, слой которой не выводится, — штатный исход.
Отказом команды SHALL быть: пустой журнал, отсутствие хотя бы одной свёрнутой доставки, отмена и любая ошибка окружения. Пустая витрина совпадает по отпечатку с пустой витриной, поэтому прогон по пустому журналу выглядит идеальной сходимостью — а все умолчания подыгрывают такому запуску: конфига может не быть вовсе, и тогда пути указывают в рабочий каталог процесса. Человек, выполнивший напечатанную процедуру, заменил бы витрину пустой.
Отчёт значений точек, имён метрик, имён устройств и содержимого тел содержать MUST NOT: отпечаток берёт содержимое хешем. Ограничение относится к отчёту в стандартном выводе; лог свёртки живёт по правилам спеки хранения, где координаты столкновения (метрика, слой, час) разрешены явно.
Отчёт идёт в стандартный вывод человеческим текстом. Прогресс длинного прогона SHALL идти в поток ошибок, а не смешиваться с отчётом: прогон на полном архиве молчит минутами, и зависший неотличим от идущего.
Scenario: Отчёт сравнивает отпечатки
- WHEN пересборка завершилась
- THEN отчёт содержит отпечаток рабочей витрины и отпечаток пересобранной
- AND прямо называет, совпали они или нет
- AND называет, изменилось ли число доставок в рабочей базе за время прогона
Scenario: Расхождение отпечатков не является отказом
- WHEN отпечаток пересобранной витрины отличается от рабочей, и при этом хотя бы одна доставка свёрнута
- THEN команда завершается успешно, а расхождение названо в отчёте
Scenario: Пустой журнал — отказ, а не идеальная сходимость
- WHEN в архиве не нашлось ни одного тела
- THEN команда завершается ненулевым кодом
- AND процедуры подмены не печатает
Scenario: Ни одна доставка не свернулась
- WHEN журнал непуст, но свернуть не удалось ни одной доставки
- THEN команда завершается ненулевым кодом
- AND процедуры подмены не печатает
Scenario: Приезд доставок за время прогона отменяет подмену
- WHEN число доставок в рабочей базе за время прогона изменилось
- THEN отчёт называет разницу
- AND процедуры подмены не печатает
Scenario: Отчёт после отмены не сравнивает неизмеренного
- WHEN прогон отменён
- THEN отчёт не содержит ни ответа о совпадении отпечатков, ни разницы числа доставок
Scenario: Рабочей базы нет вовсе
- WHEN файла рабочей базы не существует
- THEN пересборка идёт по одним подобранным телам
- AND отчёт называет, что сверять не с чем и что заголовки доставок не восстанавливаются
Scenario: Отчёт не раскрывает данных о здоровье
- WHEN отчёт напечатан
- THEN он не содержит ни значений точек, ни имён метрик, ни имён устройств