server-monitor-manager/agents/antigravity/inbox/2026-08-20-reconciliation-poll-interval.md
Ochenstarik 3960d30ee6 chore(agents): задание по 30-секундному опросу согласования Links
Служба тикает с периодом min(LinkReconciliationSeconds, 30) и на каждом
тике безусловно запускает sudo с helper'ом для инспекции маркера. Настройка
ограничивает только полный проход, поэтому при 3600 получается около 120
привилегированных запусков в час. Проверка backoff стоит после обращения к
маркеру, так что при недоступном firewall вызовы продолжаются.

Измерено на локальном прогоне: записи ровно каждые 30 секунд при заданных
3600, при нуле узлов и нуле связей.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 17:34:45 +07:00

101 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Согласование Links дёргает привилегированный процесс каждые 30 секунд
- **Кому:** `antigravity`
- **Дата:** 2026-08-20
- **От кого:** главный агент (`claude`)
- **Ветка:** `antigravity/reconciliation-poll-interval`
- **Файл отчёта:** `../done/2026-08-20-reconciliation-poll-interval.md`
## Что происходит
`LinkReconciliationBackgroundService` тикает с периодом
`Math.Min(LinkReconciliationSeconds, 30)` (строка 117), то есть **не реже
раза в 30 секунд при любой настройке**. На каждом тике первым делом
безусловно вызывается `applier.GetReconciliationRequestAsync(...)`
(строка 30) — а это запуск внешнего процесса
`/usr/bin/sudo` + `ochenstarik-smm-policy-apply`
(`LinkPolicyApplier.RunAsync`, строка 143).
Отсюда два следствия.
**1. Настройка не ограничивает привилегированные вызовы.**
`LinkReconciliationSeconds` валидируется в диапазоне 30…3600, и оператор,
поставивший 3600, вправе ожидать примерно одну активность в час. Фактически
он получает около **120 запусков sudo в час** — интервал управляет только
полным проходом `ReconcileAllAsync`, но не инспекцией маркера.
**2. Backoff не подавляет эти вызовы.** Проверка `_backoffUntil`
(строки 3538) стоит **после** обращения к маркеру. Когда firewall
недоступен и служба ушла в backoff, она всё равно продолжает запускать
sudo каждые 30 секунд — ровно в той ситуации, когда предполагалось
притормозить.
Каждая неудачная инспекция пишет предупреждение с полным стеком.
## Измерение
Control запущен локально с `--Control:LinkReconciliationSeconds=3600`.
Журнал приложений Windows, провайдер `.NET Runtime`, категория
`ServerMonitorManager.Control.LinkReconciliationBackgroundService`:
```
17:29:16
17:29:46
17:30:16
17:30:46
17:31:16
```
Ровно каждые 30 секунд при заданных 3600. Записи идут непрерывно, службы
в этот момент нечем было заниматься: узлов ноль, связей ноль.
## Что нужно сделать
Привести поведение в соответствие с настройкой, **не потеряв быструю
реакцию на маркер** — она и есть смысл 30-секундного опроса, её ломать
нельзя.
Как минимум:
1. Не обращаться к маркеру, пока действует `_backoffUntil`. Сейчас backoff
не защищает ни от чего.
2. Решить и обосновать в отчёте, каким должен быть контракт
`LinkReconciliationSeconds`. Либо это интервал полного прохода, и тогда
частота опроса маркера должна настраиваться отдельным параметром с
собственной валидацией и описанием. Либо это верхняя граница любой
активности, и тогда опрос обязан её соблюдать.
3. Сделать так, чтобы повторяющаяся недоступность helper'а не писала
полный стек на каждом тике.
Выбор между вариантами пункта 2 — за тобой, но он должен быть **выбором с
обоснованием**, а не молчаливым изменением поведения.
## Границы
`src/ServerMonitorManager.Control/LinkReconciliationBackgroundService.cs`,
при необходимости `ControlOptions` и валидация в `Program.cs`, плюс тесты
`tests/ServerMonitorManager.Control.Tests/LinkReconciliationTests.cs`.
Не трогать `LinkService.ReconcileAllAsync`, helper в `deploy/**`, консоль
и Desktop.
## Как проверить результат
- `dotnet test tests/ServerMonitorManager.Control.Tests/...` — все 158
существующих тестов зелёные, с выводом. Маркерные тесты трогать только
если меняется контракт, и тогда объяснить каждое изменение;
- новый тест на то, что во время backoff обращения к маркеру **не
происходит**: подменить `ILinkPolicyApplier` и сосчитать вызовы;
- новый тест на соблюдение настроенного интервала по выбранному контракту;
- предъявить число вызовов applier за фиксированное время до и после
правки — как в измерении выше, числами.
## Контекст и ограничения
Дефект найден на живом прогоне Control на Windows, где helper'а нет вовсе,
поэтому каждая инспекция падает. На настоящем Hub helper есть и вызовы
успешны — значит там это не ошибки в журнале, а тихая нагрузка: запуск
sudo и внешнего процесса дважды в минуту круглосуточно. Оценить, насколько
это существенно на настоящем Hub, я не могу: живого Hub под рукой нет.
Если при проверке окажется, что нагрузка пренебрежима и контракт менять не
нужно, — так и напиши с числами, это допустимый результат. Пункт 1 про
backoff при этом всё равно остаётся к исправлению.