21 lines
4.2 KiB
Markdown
21 lines
4.2 KiB
Markdown
# Итоги: защита от пустой выдачи после потери базы (находка 1 ревью)
|
||||
|
|
|
|||
|
|
План: `docs/plan-loss-guard.md`. Источник: `docs/review-2026-09-21.md`.
|
|||
|
|
|
|||
|
|
## Сделано
|
|||
|
|
- **Метка потери** (`db._recover`): при порче базы без исправных копий пишется `db_recreated.json` (до создания базы) и создаётся новая пустая база; соединение сразу рабочее (раньше первый запрос получал 503, следующие - `200 []`). Журнал изменений новой базы сдвигается общим `_reset_journal` (вынесен из `_restore_backup`): курсоры старой базы дают `410`.
|
|||
|
|
- **Блокировка выдачи:** `GET /addresses` и `GET /addresses/diff` отвечают `503` с `Retry-After: 300`, пока по запрошенным типам данные не собраны заново. Тип блокируется, если для него в `config.json` есть источники, а в базе нет значений; тип без источников не блокируется. Нечитаемый конфиг - блокировка сохраняется.
|
|||
|
|
- **Снятие метки:** `db.settle_recreated` в конце каждого запуска сбора (ASN, FQDN, CLI); ручное снятие - удалить `db_recreated.json`.
|
|||
|
|
- **`/health`:** поле `db_recreated` (`at`, `pending`, без путей); при `pending` статус `degraded`.
|
|||
|
|
- **Прочее:** `db_recreated.json` в `.gitignore`/`.dockerignore`, README (раздел о восстановлении, `/health`), находка 1 в отчёте ревью отмечена исправленной.
|
|||
|
|
- **Тесты:** 2 новых (метка, курсор, снятие; API: 503 на обоих эндпоинтах, тип без источников, `/health`, возобновление) и 1 обновлён. Всего 24, в контейнере 24 passed. Добавлен `tests/conftest.py`: автоматическая изоляция файлов состояния всех тестов во временный каталог (без неё один из тестов оставлял метку в каталоге проекта, и следующий тест получал 503).
|
|||
|
|
|
|||
|
|
## Проверка
|
|||
|
|
- Отдельные процессы (демон и API, реальный DNS): после сбора `example.com` выдача есть; порча `ripe.db` без копий -> `/addresses` и `/addresses/diff` 503, `Retry-After: 300`, `/health` `degraded` и `db_recreated: {pending: true}`, запрос `type=cidr` (ASN не настроены) -> `[]` 200; повторный `POST /collect` -> 200 с данными, `/health` `ok`, `db_recreated.json` удалён.
|
|||
|
|
- Docker Compose (отдельный проект, порт 18000, стенд убран): тот же сценарий в томе, оба сервиса `healthy`.
|
|||
|
|
- В первом ручном прогоне сбор не запустился из-за ошибки в моём скрипте (заголовки не разделились по словам, 401); прогон повторён.
|
|||
|
|
|
|||
|
|
## Замечания
|
|||
|
|
- Пока RIPE или DNS недоступны после потери, выдача остаётся 503: так задумано (лучше 503, чем пустой список); обход - удалить `db_recreated.json`.
|
|||
|
|
- **Не распознаётся как потеря:** удаление файла базы вручную (порчи нет, пустая база создаётся без метки) и чистая установка. Возможное продолжение: при отсутствии базы и наличии копий восстанавливаться из них.
|
|||
|
|
- Тип с источниками, для которого сбор вообще ничего не находит (например, все адреса FQDN отфильтрованы как неглобальные), останется в ожидании; при необходимости - удалить метку вручную.
|