feat(generator): глагол next-day — следующий модельный день от слепка
- Зачем:
- режим кормления стенда порциями: менти триггерит «следующий день»,
видит полный цикл DWH за один шаг (задача 13, вариант 2 — генерация
от слепка T_end).
- Что:
- новый ограниченный режим next-day: восстановление мира из state,
генерация ровно [T_end, T_end+24h), публикация данные -> state ->
манифест (манифест — точка фиксации, автоотката нет).
- операция next-day в DAG generator_control: своя предпроверка границы
вместо clean-guard, идемпотентность через параметр expected_t_end.
- цепочка границ — накопительное поле boundaries в манифесте, старый
формат читается как [T0, T_end]; импорт не изменён.
- новая проверка цепочки (make generated-history-chain-check): непарные
счётчики и однородность по каждой границе, явный статус нулевого
стыка, хвост за границей по всем четырём топикам, литералы в UTC
с микросекундами.
- документация OPERATIONS.md: глагол, предпроверка, восстановление
после сбоя, ограничение retention; в задаче 13 — решения двух слепых
ревью постановки и кода с аргументами отклонений.
- Проверка:
- make test: 204 теста генератора + 31 контракт корня, зелёные.
- make generated-history-chain-check: зелёный, 2 внутренние границы,
непарные счётчики нулевые; учебный цикл: DM 322 -> 10026 -> 19196
за два next-day подряд.
- make generated-history-runtime-check (регрессия задачи 20): зелёный.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+45
-3
@@ -14,6 +14,8 @@
|
||||
- `CHECK_LIVE_SEAM=0 make generated-history-check` (повторяемая проверка
|
||||
ClickHouse и Superset после прогона только стартовой истории)
|
||||
- `make generated-history-runtime-check` (короткая проверка стыка backfill/live)
|
||||
- `make generated-history-chain-check` (проверка завершённых стыков между
|
||||
порциями истории)
|
||||
- `make ddl` (применяет SQL из `sql/ddl/00_databases.sql` и `sql/ddl/*/*.sql` в ClickHouse)
|
||||
- `make data` (архивный путь: заливает `data/*.jsonl` в Kafka; не основной источник аналитики)
|
||||
- `make transform` (запускает batch-процесс ODS -> DDS -> DM)
|
||||
@@ -59,19 +61,55 @@ volumes или live-генератором. Для стыка backfill/live от
|
||||
дождаться `success`;
|
||||
- `import` — импортировать портативный артефакт, затем запустить
|
||||
`etl_pipeline` и дождаться `success`;
|
||||
- `next-day` — восстановить мир из state, добавить 24 модельных часа,
|
||||
затем запустить `etl_pipeline` и дождаться `success`;
|
||||
- `check` — сверить ClickHouse с manifest из Kafka.
|
||||
- Параметры:
|
||||
- `operation` (`backfill` / `import` / `check`);
|
||||
- `operation` (`backfill` / `import` / `next-day` / `check`);
|
||||
- `profile` — список берётся из `PROFILES` генератора;
|
||||
- `duration` — `6h`, `2d` и т.п.; пусто означает длительность профиля;
|
||||
- `seed`, `model_time_speed` — необязательные переопределения мира;
|
||||
- `artifact_path` — для `backfill` путь сохранения, для `import` путь чтения.
|
||||
- `artifact_path` — для `backfill` путь сохранения, для `import` путь чтения;
|
||||
- `expected_t_end` — необязательная ожидаемая граница перед `next-day`.
|
||||
При расхождении запуск показывает ожидаемое и фактическое значения.
|
||||
|
||||
Backfill/import требуют чистый стенд: пустые data-топики Kafka и пустые
|
||||
`stg.*_raw`. При отказе очистите стенд через `make clean`. Операции `continue`
|
||||
в DAG нет: live-генератор — долгоживущий сервис, его запускают с консоли через
|
||||
`make generator-continue`.
|
||||
|
||||
`next-day` работает на непустом стенде и не использует проверку чистоты.
|
||||
Перед записью пульт требует manifest, state ровно на его `T_end` и остановленный
|
||||
live-генератор. Настройки мира берутся из manifest; поля `profile`, `duration`,
|
||||
`seed` и `model_time_speed` формы для этой операции не применяются. Один запуск
|
||||
добавляет полуоткрытый диапазон `[T_end, T_end + 24h)` в UTC. Новая граница
|
||||
появляется в `boundaries`; старый manifest без поля читается как `[T0, T_end]`.
|
||||
Расписание остаётся выключенным (`schedule=None`), а `max_active_runs=1` не даёт
|
||||
двум доливкам выполняться параллельно.
|
||||
|
||||
После двух доливок проверьте завершённые стыки:
|
||||
|
||||
```bash
|
||||
make generated-history-chain-check
|
||||
```
|
||||
|
||||
Проверка проходит по внутренним границам `boundaries`, ищет непарные строки и
|
||||
смену browser/referer/utm внутри переходящих визитов. Она не меняет
|
||||
`make generated-history-runtime-check` для стыка backfill/live.
|
||||
|
||||
Точка фиксации `next-day` — новый manifest. Порядок записи: data-топики, state,
|
||||
manifest. Автоматического отката нет. Если запуск упал до публикации manifest,
|
||||
не повторяйте доливку поверх возможного хвоста. Очистите стенд и переимпортируйте
|
||||
последний исправный портативный артефакт, затем повторите `next-day`.
|
||||
|
||||
Текущая версия пересчитывает накопительные счётчики и контрольные суммы по всей
|
||||
доступной истории data-топиков Kafka. Поэтому время выполнения и расход памяти
|
||||
каждой доливки растут вместе с историей. Стандартный срок хранения Kafka тоже
|
||||
ограничивает долгую работу стенда. Для ручного учебного цикла запускайте
|
||||
соседние дни без долгих пауз. Перед включением расписания отдельная задача
|
||||
должна выбрать одно из решений: бессрочное хранение data-топиков или новый
|
||||
формат накопительного состояния manifest.
|
||||
|
||||
Перед запуском `etl_pipeline` пульт проверяет, что DAG не стоит на паузе. Если
|
||||
стоит, задача падает сразу с подсказкой снять паузу в UI или командой:
|
||||
|
||||
@@ -165,7 +203,7 @@ make generator-logs
|
||||
| `GEN_MODEL_T_END` | Правая граница стартовой истории для `backfill` | пусто |
|
||||
| `GEN_MODEL_TIMEZONE` | Часовой пояс модельных часов для дневного коэффициента | `UTC` |
|
||||
| `GEN_MODEL_TIME_SPEED` | Сколько модельных секунд проходит за одну настенную секунду | `1` |
|
||||
| `GEN_RUN_MODE` | Режим генератора | `live` |
|
||||
| `GEN_RUN_MODE` | Режим: `live`, `backfill` или `next-day` | `live` |
|
||||
| `GEN_LAUNCH_PROFILE` | Имя профиля запуска для логов | `ci` |
|
||||
| `GEN_STARTUP_HISTORY_ARTIFACT` | JSON-файл для экспорта стартовой истории в режиме `backfill` | пусто |
|
||||
| `GEN_STATE_ENABLED` | Сохранять state v3 между рестартами | `true` |
|
||||
@@ -254,6 +292,10 @@ GEN_HISTORY_DURATION=2d make generated-history-analytics
|
||||
контрольными числами. При live-запуске с теми же настройками генератор видит,
|
||||
что state совпадает с manifest, и стартует ровно с `T_end` без настенной дельты.
|
||||
|
||||
Новый backfill записывает `boundaries=[T0, T_end]`. Каждый успешный `next-day`
|
||||
добавляет одну границу, сдвигает `model_t_end` и пересчитывает накопительные
|
||||
счётчики и контрольные суммы по всей истории.
|
||||
|
||||
Если историю нужно сохранить в файл и восстановить на чистом стенде без новой
|
||||
генерации, используйте [runbook стартовой истории](./runbooks/startup-history.md).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user