docs(generator): добавлена задача уборки сервиса
- Зачем: - перед задачей активных визитов нужно отделить модель генератора от сервисной обвязки. - Что: - добавлена спека уборки сервиса генератора перед задачей 03. - добавлена промежуточная issue 02.5 с критериями приёмки. - уточнены требования к Dockerfile и временному тиковому слою. - задача 03 заблокирована новой задачей уборки. - Проверка: - просмотрен staged diff через `git diff --cached --stat`.
This commit is contained in:
@@ -0,0 +1,52 @@
|
|||||||
|
Status: ready-for-agent
|
||||||
|
|
||||||
|
# Уборка сервиса генератора перед активными визитами
|
||||||
|
|
||||||
|
## What to build
|
||||||
|
|
||||||
|
Разнести текущий `generator/generator.py` на понятные модули, не меняя внешнее
|
||||||
|
поведение генератора. Цель — подготовить код к задаче 03, где появятся активные
|
||||||
|
визиты между тиками.
|
||||||
|
|
||||||
|
Источник решений: `docs/specs/2026-06-11-generator-service-cleanup.md`,
|
||||||
|
`docs/specs/2026-06-10-generator-math-model.md`, задачи 01-03 в этом каталоге.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- [ ] Генеративная модель визита отделена от Kafka, состояния, метрик и
|
||||||
|
сервисного цикла.
|
||||||
|
- [ ] Код загрузки и индексации JSONL-сида вынесен из сервисного слоя.
|
||||||
|
- [ ] Расчёт интенсивности отделён от генерации одного визита.
|
||||||
|
- [ ] Kafka publisher, Kafka-state и создание служебных топиков не смешаны с
|
||||||
|
генеративной моделью.
|
||||||
|
- [ ] `generator/generator.py` остаётся тонкой точкой входа или совместимым
|
||||||
|
фасадом, чтобы не ломать запуск и тесты без причины.
|
||||||
|
- [ ] `generate_tick_batch()` не остаётся в чистой генеративной модели визита:
|
||||||
|
он вынесен в переходный тиковый слой и подготовлен к замене активными визитами
|
||||||
|
в задаче 03.
|
||||||
|
- [ ] Dockerfile и запуск контейнера обновлены под новую структуру файлов.
|
||||||
|
- [ ] Все существующие тесты генератора проходят.
|
||||||
|
- [ ] README генератора кратко отражает новую структуру файлов.
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
- Не реализовывать активные визиты между тиками.
|
||||||
|
- Не добавлять популяцию пользователей и возвраты.
|
||||||
|
- Не вводить состояние версии 2.
|
||||||
|
- Не менять Kafka-топики и формат событий.
|
||||||
|
- Не удалять `generator_batch_history`, если отдельно не доказано, что он больше
|
||||||
|
не нужен.
|
||||||
|
|
||||||
|
## Blocked by
|
||||||
|
|
||||||
|
- `.scratch/feature-data-generator/issues/02-visit-page-path-and-monotonic-time.md`
|
||||||
|
|
||||||
|
## Blocks
|
||||||
|
|
||||||
|
- `.scratch/feature-data-generator/issues/03-tick-stream-with-active-visits.md`
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
|
Задача появилась после разбора распухания сервиса: первые два среза уже внесли
|
||||||
|
новую модель визита, а третий срез добавит состояние активных визитов. Перед ним
|
||||||
|
нужно отделить модель, тиковый слой и Kafka-интеграцию.
|
||||||
@@ -31,6 +31,6 @@ Status: ready-for-agent
|
|||||||
## Blocked by
|
## Blocked by
|
||||||
|
|
||||||
- `.scratch/feature-data-generator/issues/02-visit-page-path-and-monotonic-time.md`
|
- `.scratch/feature-data-generator/issues/02-visit-page-path-and-monotonic-time.md`
|
||||||
|
- `.scratch/feature-data-generator/issues/02-5-generator-service-cleanup.md`
|
||||||
|
|
||||||
## Comments
|
## Comments
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
# Уборка сервиса генератора перед активными визитами
|
||||||
|
|
||||||
|
Дата: 2026-06-11
|
||||||
|
Статус: Draft
|
||||||
|
Связано: [спека математической модели](./2026-06-10-generator-math-model.md),
|
||||||
|
[спека иерархической переработки](./2026-06-09-generator-rework-hierarchical.md),
|
||||||
|
[`generator/KNOWN_ISSUES.md`](../../generator/KNOWN_ISSUES.md),
|
||||||
|
задачи `.scratch/feature-data-generator/issues/01..07`.
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
После первых двух срезов новый генератор уже умеет строить связанный визит и
|
||||||
|
путь по страницам, но сервисный код начал распухать. В одном
|
||||||
|
`generator/generator.py` смешаны генеративная модель, чтение сида, тиковая
|
||||||
|
логика, Kafka, состояние, история пачек, метрики и запуск сервиса.
|
||||||
|
|
||||||
|
Следующая задача — активные визиты между тиками — добавит новый слой состояния.
|
||||||
|
Если продолжить в текущей форме, этот слой ляжет поверх временного
|
||||||
|
`generate_tick_batch()`, который набирает тик целыми визитами и не соответствует
|
||||||
|
целевой модели.
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
- Разнести код генератора по понятным учебным модулям без изменения внешнего
|
||||||
|
поведения сервиса.
|
||||||
|
- Подготовить место для задачи 03: активные визиты должны появиться в отдельном
|
||||||
|
тиковом слое, а не внутри большого `generator.py`.
|
||||||
|
- Явно отделить временные части старой модели от контрактов, которые надо
|
||||||
|
сохранить.
|
||||||
|
- Сохранить прежние команды запуска, Kafka-топики, формат сообщений и полезные
|
||||||
|
метрики.
|
||||||
|
|
||||||
|
## Non-goals
|
||||||
|
|
||||||
|
- Не реализовывать активные визиты из задачи 03.
|
||||||
|
- Не добавлять популяцию пользователей, возвраты, калибровку интенсивности или
|
||||||
|
состояние версии 2.
|
||||||
|
- Не менять DDL, ETL, витрины или Superset.
|
||||||
|
- Не делать большой перепил поведения генератора под видом уборки.
|
||||||
|
|
||||||
|
## Current state
|
||||||
|
|
||||||
|
`generator/generator.py` содержит около тысячи строк и несколько разных
|
||||||
|
ответственностей:
|
||||||
|
|
||||||
|
- `Config` — настройки;
|
||||||
|
- `EventDictionary` — чтение и индексация JSONL-сида;
|
||||||
|
- `EventGenerator` — генерация визитов, страниц, пауз и интенсивности;
|
||||||
|
- `BatchRecord`, `KafkaBatchHistory` — история пачек в Kafka;
|
||||||
|
- `GeneratorState`, `KafkaStateManager` — состояние версии 1;
|
||||||
|
- `KafkaPublisher`, `ensure_topics` — работа с Kafka;
|
||||||
|
- `GeneratorService` — метрики, запуск, основной цикл.
|
||||||
|
|
||||||
|
`generate_tick_batch()` сейчас является переходным механизмом: он добирает
|
||||||
|
событийный бюджет полными визитами. Это допустимо после задач 01-02, но должно
|
||||||
|
быть заменено в задаче 03 тиковым слоем с активными визитами.
|
||||||
|
|
||||||
|
## Options considered
|
||||||
|
|
||||||
|
- **Минимальная уборка в одном файле.** Быстро, но файл останется тяжёлым и
|
||||||
|
следующая задача снова его раздует.
|
||||||
|
- **Разнести код по модулям.** Чище для чтения, лучше соответствует учебной
|
||||||
|
цели и даёт место для активных визитов.
|
||||||
|
- **Сначала выбросить лишнее.** Может заметно сократить код, но требует решения,
|
||||||
|
какие сервисные возможности больше не нужны.
|
||||||
|
|
||||||
|
## Recommended approach
|
||||||
|
|
||||||
|
Принят смешанный вариант: разнести код по модулям и по ходу явно отметить или
|
||||||
|
удалить очевидно временные части, если они не являются внешним контрактом.
|
||||||
|
|
||||||
|
Целевая форма:
|
||||||
|
|
||||||
|
- `generator/config.py` — конфигурация и её валидация;
|
||||||
|
- `generator/dictionary.py` — загрузка и индексы исходных JSONL;
|
||||||
|
- `generator/generation.py` — чистая генеративная модель визита, страниц и пауз;
|
||||||
|
- `generator/intensity.py` — расчёт бюджета активности: Пуассон, часовой
|
||||||
|
коэффициент, jitter;
|
||||||
|
- `generator/kafka_io.py` — Kafka publisher, создание топиков, Kafka-state;
|
||||||
|
- `generator/state.py` — сериализуемое состояние генератора;
|
||||||
|
- `generator/service.py` — основной сервисный цикл и метрики;
|
||||||
|
- `generator/generator.py` — тонкая точка входа или совместимый фасад для
|
||||||
|
старых импортов тестов.
|
||||||
|
|
||||||
|
Сейчас `generator/` не оформлен как Python-пакет: тесты импортируют
|
||||||
|
`generator/generator.py` как модуль `generator`, а Dockerfile копирует только
|
||||||
|
`generator.py`. В рамках этой уборки нужно сохранить совместимость импортов и
|
||||||
|
обновить контейнерный запуск под новую структуру файлов; превращать каталог в
|
||||||
|
пакет через `__init__.py` не требуется.
|
||||||
|
|
||||||
|
Точное разбиение может быть чуть проще, если это уменьшит шум, но граница между
|
||||||
|
моделью генерации, тиковым runtime и Kafka-интеграцией должна быть явной.
|
||||||
|
|
||||||
|
## Decisions and rejected alternatives
|
||||||
|
|
||||||
|
- **Принято:** уборка идёт перед задачей 03. Причина: активные визиты добавляют
|
||||||
|
новый слой состояния, и его нельзя удобно встроить в текущий монолит.
|
||||||
|
- **Принято:** внешнее поведение генератора не меняется. Цель задачи — форма
|
||||||
|
кода, а не новая модель данных.
|
||||||
|
- **Принято:** `generate_tick_batch()` считать временным переходным механизмом.
|
||||||
|
После задачи 03 тик должен выпускать созревшие события активных визитов.
|
||||||
|
- **Отклонено:** ограничиться перестановкой функций внутри `generator.py`.
|
||||||
|
Это не решает учебную читаемость и не создаёт ясного места для следующих
|
||||||
|
срезов.
|
||||||
|
- **Отклонено:** удалить историю пачек без отдельного решения. Её можно
|
||||||
|
упростить или вынести, но пока не доказано, что она не нужна для демо и
|
||||||
|
мониторинга.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
- Все существующие тесты генератора проходят.
|
||||||
|
- Импорты, которые используют тесты, либо обновлены, либо сохранены через фасад
|
||||||
|
`generator/generator.py`.
|
||||||
|
- `generate_batch()` продолжает строить один связанный визит с монотонным
|
||||||
|
временем, как после задач 01-02.
|
||||||
|
- Временный `generate_tick_batch()` не остаётся в чистой модели визита: он вынесен
|
||||||
|
в переходный тиковый слой или явно подготовлен к замене задачей 03.
|
||||||
|
- Сервисный контур продолжает публиковать в те же четыре Kafka-топика:
|
||||||
|
`browser_events`, `location_events`, `device_events`, `geo_events`.
|
||||||
|
- Dockerfile и запуск контейнера учитывают новую структуру файлов.
|
||||||
|
- В коде есть ясное место, куда задача 03 добавит активные визиты без расширения
|
||||||
|
Kafka-слоя и без переписывания генерации одного визита.
|
||||||
|
|
||||||
|
## Documentation impact
|
||||||
|
|
||||||
|
- После реализации уборки обновить `generator/README.md`: описать новую
|
||||||
|
структуру файлов и убрать формулировки, которые привязаны к одному
|
||||||
|
`generator.py`.
|
||||||
|
- Если по ходу будет принято решение удалить или заменить `generator_batch_history`,
|
||||||
|
это должно быть отдельно отражено в README и в задаче реализации.
|
||||||
Reference in New Issue
Block a user