Цена читающего маршрута: чекпойнт WAL по таймеру и условный запрос
- рядом с воркером свёртки живёт горутина, раз в минуту разбирающая журнал пассивным чекпойнтом; «журнал не разбирается» видно строкой владельцу, а не только по `df`. Признак — пара чисел, а не флаг занятости: тот молчит под удерживаемым читателем (`busy=0` при 6256 страницах и пяти перенесённых), а при занятой блокировке отдаёт `-1` вместо ответа, и `-1 >= -1` читалось бы как «разобрано целиком» - каталог отвечает `304` на `If-None-Match`, не открывая снимок витрины. Метка собрана из всего, от чего зависит ответ: версии витрины (`data_version` с закреплённого соединения плюс поколение — значение локально для соединения и не переживает переоткрытия), горизонта измерения и области действия ресурса. Версия снимается до и после сборки: снятая после пометила бы устаревший снимок свежим номером - предел и дедлайн ответа отложены в задачу Read API точек вместе с измеренной ценой первого запроса; попутно починен флаки-тест чужой задачи, искавший значение точки в сыром буфере записи лога
This commit is contained in:
@@ -36,10 +36,26 @@
|
||||
величины выглядят как «0.5», означая разное; полярность придётся назвать вслух в
|
||||
`architecture.md`, иначе через полгода два места кода поймут поле по-разному.
|
||||
|
||||
**Предел размера ответа тоже здесь.** У каталога его нет намеренно: правило
|
||||
размера — общее для маршрутов чтения, и задавать его мимоходом на первой ручке
|
||||
значило бы решить контракт до того, как известна форма тяжёлого ответа. Каталог
|
||||
станет первым его потребителем.
|
||||
**Предел размера ответа тоже здесь, и он унаследовал измеренную цену.** У
|
||||
каталога предела нет намеренно: правило размера — общее для маршрутов чтения, и
|
||||
задавать его мимоходом на первой ручке значило бы решить контракт до того, как
|
||||
известна форма тяжёлого ответа. Каталог станет первым его потребителем.
|
||||
|
||||
Цена измерена на каталоге (задача «цена читающего маршрута», закрыта чекпойнтом
|
||||
WAL и условным запросом): 693 мс и +153 МиБ живой кучи на враждебном запросе
|
||||
(20 метрик × 8 часов × 5000 точек), при том что приём в том же процессе уже даёт
|
||||
пик 768 МиБ на теле 40 МиБ. Условный запрос снял повтор, но первый запрос стоит
|
||||
столько же, а множители «метрики × окно × точки × одновременные запросы»
|
||||
по-прежнему без потолка. Сюда же уезжают отложенные варианты той задачи:
|
||||
собственный дедлайн маршрута и потоковое измерение по метрике (второе — только
|
||||
если счётчик заговорит).
|
||||
|
||||
**Машинерия условного запроса готова, и её надо взять, а не написать заново.**
|
||||
`store.VersionedRead` держит правило «версией, снятой после чтения, не
|
||||
подписывать»; `httpapi` — разбор `If-None-Match` и `304`. Метка обязана нести
|
||||
**область действия**: у точек ответ есть функция параметров запроса, и
|
||||
`etag(scope, version)` требует их канонизированную форму — иначе `304` ответит
|
||||
на другой набор данных. Детали — `docs/architecture.md`, «Условный запрос».
|
||||
|
||||
**Форма провода наследуется от каталога, и это надо решить один раз.** Сегодня
|
||||
типы `internal/catalog` сами несут json-теги, а транспорт владеет только
|
||||
|
||||
Reference in New Issue
Block a user