tasks: закрыт разбор и хранилище, начат спринт по чтению данных клиентами
- цель parsing-and-storage закрыта по своему критерию; незакрываемый остаток (новые формы от источника, ручные секции задним числом) переехал в тему parsing-completeness - цель mcp поглощена целью read-api, переименованной в «Чтение данных клиентами»: адаптер — последний шаг того же направления, а не своё - read-api-points разложена на конверт с точками, свёртку по сетке и тренировки с записями; спринт 2026-08-04 набран пятью задачами
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# Свёртка по сетке и предел размера ответа
|
||||
|
||||
- **Секция:** ядро
|
||||
- **Зачем:** Враждебный запрос к каталогу стоил 693 мс и +153 МиБ кучи, а у точек множители те же и потолка нет ни у одного
|
||||
- **Теги:** goal:read-api
|
||||
|
||||
Потребитель просит разбивку (`?from&to&bucket`) и получает свёртку по сетке —
|
||||
либо честную ошибку вместо тихо подменённой сетки, — а сервис получает
|
||||
названный предел на то, сколько он готов отдать за один запрос.
|
||||
|
||||
Вторая из трёх частей `read-api-points`. Берётся после
|
||||
[конверта ответа](read-api-envelope-and-points.md): сетка — параметр того же
|
||||
маршрута.
|
||||
|
||||
**Решение по размеру ответа принято, вариант «б».** Разбивка не задана и ответ
|
||||
не влезает — сервер сам берёт сетку погрубее и **называет её в ответе**;
|
||||
разбивка задана явно и не влезает — ошибка со списком доступных сеток, а не
|
||||
тихая подмена. Различие существенно: иначе агент, попросивший минутную сетку,
|
||||
получит суточные суммы и не узнает об этом.
|
||||
|
||||
**Порог неполного ведра решается здесь, и вместе с ним — его полярность.**
|
||||
Измерению рода агрегации порог не понадобился, свёртке в ответе он нужен, а
|
||||
готовые решения задают его **противоположно**: Graphite `xFilesFactor` — доля
|
||||
обязательно известных точек (умолчание 0.5 при роллапе и 0 при рендере, один
|
||||
параметр с двумя умолчаниями), RRDtool `xff` — доля допустимо неизвестных. Обе
|
||||
величины выглядят как «0.5», означая разное; полярность придётся назвать вслух в
|
||||
`architecture.md`, иначе через полгода два места кода поймут поле по-разному.
|
||||
|
||||
**Цена измерена, и она унаследована.** На каталоге враждебный запрос
|
||||
(20 метрик × 8 часов × 5000 точек) дал 693 мс и +153 МиБ живой кучи, при том что
|
||||
приём в том же процессе уже даёт пик 768 МиБ на теле 40 МиБ. Условный запрос
|
||||
снял повтор, но первый запрос стоит столько же, а множители «метрики × окно ×
|
||||
точки × одновременные запросы» по-прежнему без потолка. Сюда же уезжают
|
||||
отложенные варианты задачи «цена читающего маршрута»: собственный дедлайн
|
||||
маршрута и потоковое измерение по метрике — второе только если счётчик
|
||||
заговорит.
|
||||
|
||||
Инвариант, который здесь легче всего нарушить: **нижний слой HAE не
|
||||
суммируется** ни при какой сетке — это интерполяция, а не сэмплы.
|
||||
|
||||
## Критерии приёмки
|
||||
|
||||
- «шаги за неделю по дням» отвечаются одним запросом, и в ответе названа
|
||||
фактическая сетка — оракул: запрос к поднятому сервису на живом архиве
|
||||
- явно заданная сетка, которая не влезает в предел, даёт ошибку со списком
|
||||
доступных сеток, а не подменённый ответ — оракул: тест
|
||||
- неполное ведро обрабатывается объявленным порогом, и полярность порога
|
||||
названа в `docs/architecture.md` вслух — оракул: тест на границе плюс глазами
|
||||
по разделу
|
||||
- нижний слой HAE не суммируется ни при какой сетке — оракул: тест на
|
||||
накопительной метрике, у которой есть и нижний, и часовой слой
|
||||
|
||||
## Рамки
|
||||
|
||||
Схема не трогается, данные только читаются, сервис перезапускается. Берётся
|
||||
после конверта ответа. Против `./data` — только `task up` / `task run`.
|
||||
|
||||
Связано: `docs/architecture.md` → «Свёртка и размер ответа»; идея
|
||||
[NDJSON-потока](ndjson-stream.md) закрывает другую сторону того же предела.
|
||||
Reference in New Issue
Block a user