Зерновой мир: мини-манифест и заливка при make up #42
Notifications
Due Date
No due date set.
Depends on
#41 Сериализатор, приёмники и проигрыватель с CLI
ddmitry/clickstream-data-platform
#43 Типизированный ODS: ods.event, строгий приём и таблица ошибок
ddmitry/clickstream-data-platform
Reference: ddmitry/clickstream-data-platform#42
Reference in New Issue
Block a user
Part of #4.
Цель
Зафиксировать «зерновой» мир конца этапа 2 — маленький срез эталонной оси
для стабильных приёмок следующих этапов — и замкнуть этап: заливка при
make upи проверка на настоящих данных.Что войдёт
seeds.py,CANONICAL_SEED,заведено в #38) — здесь оно только попадает в паспорт мини-манифеста.
счётчики, хеши по дням. Форма решается здесь — с прицелом на полный
манифест этапа 7: мини-манифест — его младший брат, не вторая правда.
Срез решён владельцем при нарезке (2026-08-01): первые 8 модельных
дней оси, понедельник–понедельник. Полная неделя с выходными плюс
первый замкнутый цикл окна K = 7: день D0 успевает замёрзнуть — этапам
3–4 есть на чём принимать и «дыхание» выручки, и заморозку. Полный
снимок 14 дней — этап 7.
make upзаливает зерновой мир через Kafka пакетным режимомпроигрывателя; счётчики против мини-манифеста идут отдельной проверкой
в
make check-clickhouse. В смоук их класть не надо: разметка целейрешена в #54, ось — кого спрашивают, а счётчики в
ods.eventсчитает самсервер и отвечает сразу. Смоук остаётся быстрой проверкой «стенд собран».
Kafka → STG → ODS. #43 закрыл свои три утверждения разовыми опытами иназвал сторожем цепочки именно их (решение владельца 7 августа 2026 года).
Отсюда требование к форме: они обязаны ловить поломку разбора — сломалась
матвью, события уехали в брак, счёт разошёлся, — а значит смотрят и на
ods.event, и на*_errors, и при расхождении показывают, где именно оно.Считать одни события мало: брак так и останется невидимым.
Что приходит готовым из #41
Тикет идёт третьим: #41 → #43 → #42, оба предшественника влиты. К его старту
на стенде стоят проигрыватель, настоящие события в топике и типизированный ODS.
Готовым приходит генератор в собственном образе, разовая служба compose на нём,
цели
make generate-batch/generate-live, ограниченная пачка с печатью числаотправленного, способ проиграть несколько дней подряд одним запуском и CLI без
состояния — всё это видно в
compose.yamlиMakefile.Отсюда работа этого тикета, которую больше некому сделать:
make up— она приходит под профилемgeneratorив
make upне входит. Снять её из-под профиля и дать ей зависимого сservice_completed_successfully. Без зависимогоup --waitсчитает успешноотработавшую разовую службу упавшей; предупреждение об этом уже стоит в
compose.yamlуclickhouse-init, и цепочкаkafka-init→clickhouse-init→airflow-initдержится ровно на нём. Заливка идётпоследней в цепи, поэтому зависимого ей придётся назначить осознанно.
порядок применения DDL решён нумерацией файлов, и последней по построению
создаётся матвью приёма (
sql/ddl/40-stg-views.sql) — она включает чтениетопика, и всё доехавшее до появления разбора (30) минует ODS молча.
Нумерацию не «выправлять»: пропуск намеренный, объяснение — в шапке файла.
up --waitдожидаетсяслужбы, а приём асинхронный: Kafka-движок копит блок и отдаёт его по
размеру либо по
stream_flush_interval_ms(умолчание 7,5 с), а зерновоймир — это около 400 тыс. сообщений. Ждать ограниченным циклом опроса с
таймаутом, а не
sleepнаугад; образцы циклов — вscripts/stand-services.sh.Решить и внести в спеку генератора (раздел 9) тем же PR
оставшийся за этим тикетом пункт раздела 9 — хеш каталога в паспорте
мира: правка цены или уровня спроса в CSV сейчас меняет мир молча.
Третий открытый пункт, интерфейс запуска, закрывает #41. После этого
раздел закрыть: подзаголовок «Остаётся открытым, за тикетами:» (раздел 9
спеки) переписать решениями или удалить.
Перф-порог снят
Решение владельца 7 августа 2026 года: автоматического порога не будет.
Спека назначила «день ≤ 30 с» до того, как генератор написали; замер 7 августа
на машине стенда — 1,7 секунды на день в 50 626 событий, в восемнадцать раз
ниже порога. Как здесь говорят о времени, решила карта целей: цена — замеренное
число с датой, а не назначенный предел (
docs/architecture/testing.md).Наблюдаемость остаётся: проигрыватель печатает тайминги генерации и доставки
раздельно, а
make upпосле этого тикета гоняет генератор по восемь дней прикаждом подъёме стенда.
Снятие доводится до спеки тем же PR, иначе она продолжит обещать проверку,
которой нет: раздел 5 (абзац «Автоматический порог один…» целиком) и строка
в разделе «Числа». Соседний абзац раздела 5 — «Остальное — наблюдаемость без
порогов» — остаётся и становится всем ответом; вместо порога туда идёт
замеренное число с датой.
Критерии приёмки
make clean && make upс нуля приводит стенд к данным зерновогомира в
ods.event;make check-clickhouseзелёный и сверяетсчётчики с мини-манифестом. Счёт обрамляется по
EventDateзернового мира: мир растёт — менти переиграет день, этап 5 добавит
следующий, — и голый счёт по таблице разойдётся с манифестом законно,
без всякой поломки.
в событиях или в браке.
мини-манифест в git, снимок в git не попадает. Внутрипрогонный повтор
проверять не надо — побайтовое совпадение двух прогонов уже держит
generator/tests/test_player.py::test_two_runs_give_the_same_file.замеренное число с датой.
make upперезамерена и записана в карту целей(
docs/architecture/testing.md): заливка зернового мира её меняет, ацена там — замер с датой.
зернового мира.
нарезке» не осталось.
Границы
amd64/arm64 — этап 7 (#9).
владельца по следующим уровням хранилища), а не проверки стенда. Находку
«это стоило бы проверять регулярно» нести туда, а не в
make check-clickhouse.Сначала прочитать
docs/architecture/testing.md— разметка целей проверки: чтоутверждает каждая и куда класть новую; там же правило про цену как замер.
профиль разовой службы и интерфейс запуска, на которых стоит раздел «Что
приходит готовым».
ограниченным циклом и довод, по которому постоянных проверок цепочки там
не осталось ни одной.
Проверка
make clean && make up && make check-clickhouse && make smokeПравка тела по решению из #54: счётчики против мини-манифеста уходят из смоука в цель проверки ClickHouse.
Разметка целей в #54 идёт по оси «кого спрашивают»: смоук отвечает «стенд собран» и обязан оставаться быстрым, а счётчики в
ods.eventсчитает сам сервер и отвечает сразу — им место рядом с договором со схемой из #43. Заодно там жеsmoke-clusterпереименовывается вcheck-clickhouse; до слияния #54 цель зовётся прежним именем, так что порядок работ этот тикет не связывает.Тронуты: «Что войдёт», первый критерий приёмки, «Сначала прочитать», «Проверка».
Хэндовер из #41 дописан (грилинг постановки #41, 7 августа 2026 года).
Тикет получил раздел «Что приходит готовым из #41» и работу, которая из этого
следует. Главное, чего в теле не было и обо что исполнитель упёрся бы на первой
минуте: разовая служба заливки приходит под профилем и в
make upневходит — включить её и дать ей зависимого с
service_completed_successfullyпредстоит здесь. Без зависимого
up --waitсчитает успешно отработавшуюразовую службу упавшей; предупреждение об этом стоит в
compose.yamlуclickhouse-init, а заливка идёт последней в цепи, так что зависимого ейпридётся назначить осознанно.
Там же названы остальные подарки #41: генератор живёт в образе Airflow на базе
apache/airflow:3.3.0-python3.14(штатный образ несёт 3.13, и лок генератора внего не встанет), контекст сборки образа перенесён в корень репозитория,
зависимости ставятся из
uv.lock, клиент Kafka объявлен группой зависимостейгенератора, CLI без состояния, ограниченная пачка печатает число отправленного.
Заодно две правки по мелочи. Форма мини-манифеста названа не «последним»
открытым вопросом раздела 9, а одним из двух, оставшихся за этим тикетом: рядом
стоит хеш каталога в паспорте мира — правка цены или уровня спроса в CSV сейчас
меняет мир молча. Третий пункт, интерфейс запуска, закрывает #41. И снята
устаревшая оговорка «до #54 эта цель зовётся
make smoke-cluster»:переименование уже случилось.
Хэндовер переписан под контейнер; из холодного ревью связки легли четыре
правки.
#41 переиграл размещение: у генератора теперь свой образ (
python:3.14,зависимости
uv sync --frozenиз лока, каталог товаров внутри), а образAirflow не трогается — ни база, ни контекст сборки, ни список пакетов. Раздел
«Что приходит готовым» переписан под это; заодно оттуда приходит способ
проиграть несколько дней подряд одним запуском — зерновой мир это восемь дней,
и восемь стартов службы внутри
make upбыли бы плохим ответом.Исправлена ошибка вчерашнего хэндовера. Было сказано, что последней
создаётся матвью разбора, — наоборот: последней по построению создаётся матвью
приёма (
sql/ddl/40-stg-views.sql), а разбор идёт под номером 30. Выводпро порядок заливки уцелел, но по названной причине исполнитель мог полезть
«выправлять нумерацию», от чего прямо предостерегает шапка файла.
Ожидание доезда названо отдельно.
up --waitдожидается завершенияслужбы-заливки, а приём асинхронный: Kafka-движок отдаёт блок по размеру либо
по
stream_flush_interval_ms(умолчание 7,5 с), а зерновой мир — около400 тыс. сообщений. Без ограниченного цикла опроса первый критерий тикета
красен по устройству, а не по поломке. Образцы циклов — в
scripts/stand-services.sh; #43 добавлен в «сначала прочитать», потому чтодисциплина ожидания записана там.
Счёт против мини-манифеста обрамляется по
EventDateзернового мира. В томже
make check-clickhouseживёт проверка инварианта слоёв из #43, а она самавставляет управляемую пачку — голый счёт по таблице разошёлся бы с манифестом
без всякой поломки.
Мелочи: пункт «каноническое зерно — константа репозитория» был холостым, зерно
заведено ещё в #38 (
seeds.py,CANONICAL_SEED) — переформулирован в «попадаетв паспорт мини-манифеста». Заголовок, который тикет велел снять из раздела 9
спеки, назывался иначе; поправлено на существующий подзаголовок «Остаётся
открытым, за тикетами:».
Зерновой мир: мини-манифест, заливка при make up, перф-порогto Зерновой мир: мини-манифест и заливка при make upПроход той же линзой, что и по #43, 7 августа 2026 года. Тело правилось в
09:12 — до слияния #41 (14:37) и #43 (16:52), и часть его доводов за это время
умерла. Что изменилось.
Перф-порог снят целиком — решение владельца. Спека назначила «день ≤ 30 с»
до того, как генератор написали. Замер сегодня на машине стенда: 1,7 секунды
на день в 50 626 событий, файл 56 МБ. Порог в восемнадцать раз выше факта зелен
при любой правдоподобной регрессии, а карта целей уже решила, как здесь говорят
о времени: цена — замеренное число с датой, а не назначенный предел. Перф-тест
вносил ровно то, что карта отвергла. Наблюдаемость остаётся и без него:
проигрыватель печатает тайминги генерации и доставки раздельно, а
make upпосле этого тикета гоняет генератор по восемь дней при каждом подъёме стенда.
Снятие доведено до спеки мандатом в критериях — два места, раздел 5 и список
чисел, — иначе спека продолжит обещать проверку, которой нет. Заголовок тикета
поправлен.
Сказано, что счётчики унаследовали роль сторожа. После #43 они —
единственный постоянный сторож цепочки
Kafka → STG → ODS; в теле это нестояло, и исполнитель написал бы счёт по
ods.event, формально не ошибившись.Теперь названо, что они обязаны ловить: сломалась матвью разбора, события
уехали в брак, счёт разошёлся, — значит смотреть надо и на брак, и при
расхождении показывать, где оно.
Критерий про хеши переписан. «Чек-скрипт дважды подряд даёт те же хеши» уже
держит юнит-тест из #41 —
generator/tests/test_player.py::test_two_runs_give_the_same_file, он сравниваетцелые хеши двух прогонов. Ценное утверждение другое и в критерий не попадало:
хеш дня сходится с манифестом, лежащим в git, то есть мир не дрейфует между
коммитами.
Добавлен критерий на цену
make up. Заливка зернового мира её заметноменяет, а в карте целей цена — замер с датой. Без этого замер 6 августа станет
неправдой молча.
Хэндовер из #41 ужат. Описательная половина («свой образ», «зависимости из
лока», «CLI без состояния») теперь проверяется взглядом в
compose.yamlиMakefile— оба влиты. Действенная половина осталась дословно: служба приходитпод профилем
generator, включить её вmake upи дать зависимого сservice_completed_successfully.Границы пополнились одной строкой: корректность процессов хранилища заберут
отдельные даги DQ (планы владельца по следующим уровням), а не проверки стенда.
Находку «это стоило бы проверять регулярно» нести туда.
Два довода в комментариях выше умерли — не следуйте им. Обрамление счёта по
EventDateобъяснялось тем, что «в том жеmake check-clickhouseживётпроверка инварианта слоёв из #43, а она сама вставляет управляемую пачку»:
такой проверки нет, #43 не добавил в скрипт ни одной. Обрамление всё равно
нужно, и тело даёт свой довод — мир растёт. Там же счётчикам обещано место
«рядом с договором со схемой из #43»: contract-тест снят 6 августа.
Тело было 121 строку, стало 143. Выросло на две вещи, которых не хватало
(роль сторожа и цена
make up), и на объяснение реза; работы в PR при этомстало меньше — перф-тест, маркер и отдельная make-цель не пишутся.
ddmitry referenced this issue2026-08-07 20:33:32 +03:00