A validator that failed the self-check of an address no longer gets that address
again in the current round (ClaimNextQueued skips it); the validator itself stays
in service and takes all other addresses. The verdict fail is set when the number
of failed self-checks of an address reaches settings.self_check_max_attempts
(1..50, default 5, independent of the number of validators); max_retries and
retry_count are no longer used for self-check. If every working validator has
already failed the address, a new round starts and the exclusions lapse.
Migration 0012: ip_self_check_failures (permanent history per registry address),
ip_queue.sc_failures and sc_round_start_cycle (cycle_id is used instead of
attempt_number, which restarts when a queue row is recreated), the setting.
db.FailSelfCheck does it in one transaction; re-submission starts a new series.
API: self_check_max_attempts in GET/PUT /admin/config/orchestrator,
self_check_failed_on in /admin/ips/{ip} and /admin/registry/{ip}. Dashboard: the
field on /settings and the line "Self-check не прошёл на: ..." on the address
pages. Docs, plan and summary in docs/changes/.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
33 lines
4.9 KiB
Markdown
33 lines
4.9 KiB
Markdown
# Итог: повтор после сбоя self-check — на другом валидаторе
|
||
|
||
План: [2026-10-04_08-01_self-check-exclude-validator-plan.md](2026-10-04_08-01_self-check-exclude-validator-plan.md).
|
||
Статус: код написан и проверен (gofmt, build, vet, test, миграция на копии боевой БД); стенд **не пересобирался**.
|
||
|
||
## Что изменено
|
||
|
||
- **Миграция `0012_self_check_failures.sql`** (версия схемы 12): таблица `ip_self_check_failures` (история сбоев по адресу, по `registry_id`, без внешних ключей); колонки `ip_queue.sc_failures` и `ip_queue.sc_round_start_cycle`; настройка `settings.self_check_max_attempts` (`DEFAULT 5`, допустимо 1…50).
|
||
- **`db.ClaimNextQueued`** пропускает адреса, на которых этот валидатор провалил self-check в текущем раунде; адрес остаётся в очереди для других валидаторов.
|
||
- **`db.FailSelfCheck`** (одна транзакция): записывает сбой, увеличивает `sc_failures`; при `sc_failures >= потолка` — `fail`; иначе возвращает адрес в очередь без изменения `retry_count`; если рабочих валидаторов без сбоя в раунде не осталось — новый раунд. Позднее сообщение (адрес не у этого валидатора) — `ErrInvalidState`.
|
||
- **Оркестратор** (`SelfCheckResult` → `failSelfCheck`): потолок читается из настроек на каждом сбое. События: `retry_or_fail` (при `fail` — со списком валидаторов) и `validator_excluded`. `max_self_check_retries` не используется (поле в YAML осталось).
|
||
- **`SubmitIPsAs`/`SeedQueue`**: перепостановка начинает новую серию (`sc_failures = 0`, новый раунд); история остаётся.
|
||
- **API**: `GET/PUT /admin/config/orchestrator` — поле `self_check_max_attempts` (400 вне 1…50; в PUT необязательно); `self_check_failed_on` в `GET /admin/ips/{ip}` (фильтр по запуску) и `GET /admin/registry/{ip}` (все запуски).
|
||
- **Дашборд**: поле «Потолок провалов self-check на адрес» на `/settings`; строка «Self-check не прошёл на: …» на `/ips/{ip}` и `/registry/{ip}`.
|
||
- **Документы**: `USAGE.md` (новый раздел «Повтор после сбоя self-check»), `API.md`, `DASHBOARD.md`, `ADMIN_CLEANUP.md` (новая таблица в сценариях 3.1 и 3.4), `README.md`.
|
||
|
||
## Отступления от плана
|
||
|
||
1. Раунд хранится как `sc_round_start_cycle` (номер `cycle_id`), а не `sc_round_start_attempt`: `attempt_number` сбрасывается при удалении и повторном создании строки очереди, а история остаётся — новая строка получила бы чужие исключения. `cycle_id` по адресу не повторяется. Поведение для оператора то же.
|
||
2. Значение 5 задано `DEFAULT 5` колонки (покрывает и существующую строку `settings`, и чистую установку), `config.go` не менялся.
|
||
3. В `PUT` потолок необязателен — старые клиенты без поля не получают 400.
|
||
4. `validator_excluded` не пишется, если начался новый раунд (исключение сразу теряет силу).
|
||
|
||
## Проверки
|
||
|
||
- `gofmt -l` — пусто; `go build ./...`, `go vet ./...` — без ошибок; `go test ./...` — все пакеты `ok`. Две проверки версии схемы в старых тестах миграций (`TestMigration0010…`, `TestMigration0011…`) обновлены с 11 на 12.
|
||
- Новые тесты: БД (`queries_selfcheck_test.go`), оркестратор (сценарий на трёх валидаторах, потолок, один и два валидатора, смена настройки), API, дашборд.
|
||
- Миграция `0012` на копии боевой БД: версия 11 → 12, `self_check_max_attempts = 5`, повторное открытие без ошибок, таблица сбоев пуста.
|
||
|
||
## Выкладка
|
||
|
||
Не выполнена. Нужны пересборка и перезапуск `control-api` и `admin-dashboard` по процедуре (проверка пустой очереди, копия БД, тег отката `pre-self-check-exclude`, миграция `0012`); на стенде в очереди сейчас 6489 адресов `done`, `queued` нет.
|