Files
ripe-cidr-collector/docs/summary-review-fixes-5-10.md
T
ayurishchevandClaude Sonnet 5 aaf41adc79 Stage B of review fixes: daemon state lock, image build check, RIPEstat retries
Job state is changed under one RLock, the Dockerfile copies all root
modules and imports them at build time, RIPEstat requests go through a
retrying session with the sourceapp parameter (ripestat_sourceapp) and a
capped Retry-After. Adds the summary and marks review findings 5-10 fixed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 10:12:48 +03:00

29 lines
5.2 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.
# Итоги: исправления 5-10 по результатам ревью
План: `docs/plan-review-fixes-5-10.md`. Источник: `docs/review-2026-09-21.md`. Два этапа, два коммита; тестов стало 27 (было 24).
## Этап А: путь чтения (находки 5, 6, 10), коммит `d6b69d0`
- **5. Один снимок в `/addresses`:** `db.read_transaction`, одна сессия вместо трёх; курсор в `X-Changes-Cursor` берётся в том же снимке, что и данные. Функции `get_cidrs`/`get_fqdn_ips` удалены.
- **6. `/health` без путей:** в `last_restore` только `{at, backup}` (имя файла копии); каталоги, карантин и текст ошибки остаются в `last_restore.json`.
- **10. `get_changes` пакетами:** проверка наличия порциями по `PRESENCE_BATCH = 500` вместо запроса на каждое значение; `get_changes` использует `read_transaction`.
- **Проверка:** ответы шести запросов (`/addresses` с разными параметрами, `/addresses/diff`) до и после совпали побайтно; `get_changes(cursor=0)` на журнале из 12 тыс. записей: 6832 мс -> 88 мс; при параллельной записи пар ASN/FQDN старый код дал 303 несогласованных ответа из 411, новый - 0 из 601.
## Этап Б: демон, образ, внешний источник (находки 7, 8, 9)
- **7. Состояние заданий:** `_state_lock` стал `RLock`, все изменения `job_state` (`run_job`, `schedule_jobs`, `sync_schedule`) выполняются под ним; при прерывании (`SystemExit`) прежняя `last_error` сохраняется.
- **8. `Dockerfile`:** `COPY *.py ./` вместо списка модулей и проверка `import api_server, collector_daemon, db, healthcheck` на этапе сборки.
- **9. RIPEstat:** сессия `requests` с повторами (до 3, при сбоях соединения и кодах 429/500/502/503/504, паузы 0, 2, 4 с), параметр `sourceapp` (по умолчанию `ripe-cidr-collector`, ключ `ripestat_sourceapp` в `config.json`), сессия создаётся на запуск сбора и закрывается в конце. После исчерпания повторов источник пропускается, ничего не удаляется.
- **Тесты:** 2 новых (задание `backup` в демоне: регистрация, ротация по `backup_keep`; сессия RIPEstat: `sourceapp`, ключ из конфига, `None` после сбоя, настройка повторов и потолка `Retry-After`).
- **README:** `ripestat_sourceapp`, логика повторов, проверка образа.
## Проверка этапа Б
- Локальный «RIPEstat»: два ответа 503, затем 200 -> результат за 2,0 с, три запроса, в каждом `sourceapp` (значение из конфига); постоянный 429 с `Retry-After: 3600` (потолок на время проверки 1 с) -> 4 попытки за 3,0 с, источник пропущен с записью в лог.
- Сборка образа: текущий код собирается; копия проекта без `formatters.py` не собирается (падает импорт); новый модуль в корне попадает в образ без правки `Dockerfile`.
- Docker Compose (отдельный проект, порт 18000, стенд убран): три задания в `/health`, ручной сбор FQDN отработал, расписание `backup` изменено через API и применено демоном (копия появилась), `status: ok`, сервисы `healthy`, ошибок в логе нет.
- Первая попытка негативной проверки образа не выполнилась (в среде нет `rsync`): повторена через `tar`.
## Отличия от плана и замечания
- **Паузы 0, 2, 4 с, а не 1, 2, 4:** первая повторная попытка в `urllib3` идёт без паузы. Худший случай на один ASN около 46 с (4 попытки по 10 с и паузы).
- **`Retry-After` не «уважается» безусловно, а ограничен потолком `MAX_RETRY_AFTER = 30` с:** иначе ответ с `Retry-After: 3600` блокировал бы сборщик на час. В худшем случае с длинным `Retry-After` один ASN займёт до 130 с.
- `sourceapp` виден RIPE: не помещайте в него секреты; контакт администратора допустим.
- Оставлено: архитектурные замечания ревью (вынос путей в `settings.py`, разделение `api_server.py` и `cidr_collector.py`), ограничение частоты `POST /collect`, повторные запросы DNS.