11 KiB
Build 060.28 — Persistent Checkpoint and Startup Recovery
Engineering Migration Report
Контроль документа
| Свойство | Значение |
|---|---|
| Build | 060.28 |
| Статус | Completed |
| Подсистема | Market Data Acquisition / Persistent Checkpoint |
| Компонент | Trade Stream Startup Recovery |
| Дата завершения | 2026-08-01 |
| Версия | 1.0 |
Связанные документы
- Build 060.28 Architecture — архитектура, решения и подробные результаты подэтапов 060.28.0–060.28.8;
- Build 060.27 Engineering Migration Report — Persistent Market Data Storage;
- Dzentra Target Architecture — место Market Data Acquisition в целевой архитектуре Dzentra;
- Master Roadmap — дальнейшая последовательность Build.
1. Назначение Build
Build 060.28 сделал operational checkpoint Trade Stream постоянным и добавил восстановление Runtime после перезапуска процесса.
PostgreSQL Canonical Trades остаются источником рыночных фактов. Persistent checkpoint хранит только подтверждённую точку в этой истории и позволяет восстановить bounded deduplication window до подключения к бирже.
Итоговая последовательность запуска:
PostgreSQL pool + migrations
↓
checkpoint hydration или first-adoption
↓
WebSocket connect + subscription ACK
↓
REST Recovery при закрытом Live gate
↓
buffered Live в исходном порядке
↓
обычный Production Runtime
2. Завершённые подэтапы
| Подэтап | Название | Статус |
|---|---|---|
| 060.28.0 | Architecture, Contracts and Failure Policy | Accepted |
| 060.28.1 | PostgreSQL Checkpoint Schema and Migration | Accepted |
| 060.28.2 | Checkpoint Repository and Atomic Trade Commit | Accepted |
| 060.28.3 | Consistency Persistence Integration | Accepted |
| 060.28.4 | State Hydration and Deduplication Restoration | Accepted |
| 060.28.5 | Startup Recovery and ACK/Live Boundary | Accepted |
| 060.28.6 | Bootstrap and Lifecycle Integration | Accepted |
| 060.28.7 | PostgreSQL Restart and Failure Verification | Accepted |
| 060.28.8 | Final Regression and Acceptance | Accepted |
Каждый подэтап проходил отдельный read-only review. Findings исправлялись и закрывались regression-тестами до принятия.
3. Реализованная архитектура
3.1. Schema и единый repository
Migration 8 создала непартиционированную таблицу
market_data.trade_stream_checkpoints с ключом (venue, symbol).
Checkpoint ссылается на точную Canonical Trade identity через deferred
ON UPDATE/DELETE NO ACTION foreign key.
PostgresTradeRepository остаётся единственным владельцем записи
Trades и реализует узкий TradeCheckpointStorageProtocol. Новая Trade и
продвижение checkpoint выполняются одним соединением и одной
транзакцией. Expected identity и revision обеспечивают CAS-защиту от
stale writer; повтор уже зафиксированной candidate Trade идемпотентен.
Duplicate Trade обновляет provenance без продвижения persistent или in-memory checkpoint.
3.2. Consistency и Hydration
TradeStreamConsistencyController продвигает in-memory state только
после успешного durable commit. Ошибка PostgreSQL является фатальной и
не скрывается.
TradeStreamStateHydrator до запуска сети:
- загружает и проверяет persistent checkpoint;
- восстанавливает bounded rollover-aware Trade tail;
- создаёт временные
TradeStreamState; - атомарно публикует весь набор в общий State Store.
Если после Build 060.27 история уже существует, а checkpoint ещё нет,
последняя проверенная Trade один раз принимается как revision 1 без
повторного наблюдения и изменения provenance.
3.3. Startup Recovery
RuntimeStartupRecoveryCoordinator выполняет blocking Hydration и REST
Recovery через принадлежащие Runtime задачи. Cancellation ожидает уже
начатый worker, поэтому PostgreSQL pool не закрывается под выполняющейся
операцией.
Production Runtime использует одного WebSocket consumer до завершения startup. Он ожидает положительный subscription ACK с конечным timeout, складывает ранние market-сообщения в ограниченный FIFO, выполняет REST Recovery при закрытом общем gate и затем разбирает FIFO в исходном порядке.
Negative ACK, timeout, переполнение FIFO, повреждённый checkpoint или ошибка Recovery завершают startup без открытия Live processing.
3.4. Bootstrap и lifecycle
Отдельный checkpoint feature flag не добавлен. Persistent checkpoint
включается только вместе с MARKET_DATA_STORAGE_ENABLED=true и
использует тот же экземпляр PostgresTradeRepository, что и запись
Canonical Trades.
Composition не выполняет I/O и не создаёт фоновых задач. Application сохраняет порядок:
pool open → migrations → Runtime start
Runtime stop → ожидание workers → pool close
Неполная пара Trade sink/checkpoint storage отклоняется до создания сетевых компонентов.
3.5. Partitions и Retention
Foreign key временно снимается только внутри транзакции обслуживания Trade partitions и восстанавливается до commit с тем же строгим контрактом. Попытка Retention удалить активную checkpoint Trade откатывает всю операцию.
Partition Manager и atomic writer используют единый порядок блокировок:
market_data.trades parent
↓
trades_default
↓
trade_stream_checkpoints
Это исключает deadlock при одновременной записи в существующую месячную partition и создании новой.
4. Real PostgreSQL verification
Безопасный opt-in harness требует отдельную локальную базу с именем
dzentra_test_* и два явных параметра:
DZENTRA_RUN_POSTGRES_TESTS=1;DZENTRA_TEST_POSTGRES_DSN.
Реальный PostgreSQL 16 подтвердил:
- restart с восстановлением checkpoint и deduplication tail;
- first-adoption существующей истории 060.27;
- отсутствие network I/O до завершения Hydration/adoption;
- rollback ошибки до commit и восстановление после ошибки после commit;
- фатальный orphan checkpoint и REST failure при закрытом Live gate;
- ожидание blocking Hydration при cancellation;
- rollover-границы
INT32_MAX → INT32_MINи-1 → 0; - защиту активной checkpoint Trade при Partition/Retention;
- отсутствие deadlock между Partition Manager и atomic writer;
- отсутствие оставшихся tasks, threads и PostgreSQL connections.
5. Финальные результаты
Итоговая приёмка выполнена 2026-08-01:
Partition lock-order unit target: 21 passed
Restart/failure repeated ten times: 90 passed
Partition/checkpoint race ten times: 10 passed
Full PostgreSQL Storage integration: 51 passed
Full integration with PostgreSQL: 64 passed
PostgreSQL suite without opt-in: 51 skipped
Fixed stress target: 3 passed, 1 deselected
Full offline regression: 2305 passed, 69 deselected
git diff --check: clean
Untracked files whitespace check: clean
В integration и stress наборах ResourceWarning считался ошибкой.
Одноразовый PostgreSQL-контейнер после приёмки остановлен и удалён.
Итоговый read-only review не обнаружил открытых findings.
6. Границы Build
Build 060.28 намеренно не реализует:
- общий Data Access Layer и Historical Queries;
- Replay API и детерминированные replay-часы;
- подключение persistent Quote/Candle consumers;
- автоматический Retention Scheduler;
- distributed lease, leader election и HA failover;
- бесконечный Recovery retry/backoff.
Эти обязанности относятся к следующим Build. Полная итоговая ревизия документации Market Data Acquisition остаётся задачей Build 060.30.
Постороннее пользовательское изменение .gitignore не относится к
Build 060.28 и не должно включаться в его staging.
7. Итог
Build 060.28 завершён и принят.
Dzentra восстанавливает подтверждённое состояние Trade Stream из PostgreSQL после перезапуска, заполняет downtime gap через REST и только после этого продолжает Live processing. Durable history, persistent checkpoint и in-memory state теперь продвигаются в одном проверяемом порядке без скрытой потери последовательности.
Следующий этап — Build 060.29, Market Data Access and Replay.