When ripe.db is corrupted and no valid backup exists, a new empty database is created with a db_recreated.json marker; /addresses and /addresses/diff answer 503 until the collector gathers data again, /health reports db_recreated. Tests now isolate all state files via conftest. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
4.2 KiB
4.2 KiB
Итоги: защита от пустой выдачи после потери базы (находка 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/diff503,Retry-After: 300,/healthdegradedиdb_recreated: {pending: true}, запросtype=cidr(ASN не настроены) ->[]200; повторныйPOST /collect-> 200 с данными,/healthok,db_recreated.jsonудалён. - Docker Compose (отдельный проект, порт 18000, стенд убран): тот же сценарий в томе, оба сервиса
healthy. - В первом ручном прогоне сбор не запустился из-за ошибки в моём скрипте (заголовки не разделились по словам, 401); прогон повторён.
Замечания
- Пока RIPE или DNS недоступны после потери, выдача остаётся 503: так задумано (лучше 503, чем пустой список); обход - удалить
db_recreated.json. - Не распознаётся как потеря: удаление файла базы вручную (порчи нет, пустая база создаётся без метки) и чистая установка. Возможное продолжение: при отсутствии базы и наличии копий восстанавливаться из них.
- Тип с источниками, для которого сбор вообще ничего не находит (например, все адреса FQDN отфильтрованы как неглобальные), останется в ожидании; при необходимости - удалить метку вручную.