Files
dzentra_bot/docs/migrations/build_060_28.md

248 lines
11 KiB
Markdown
Raw Permalink 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.
# 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](build_060_28_architecture.md) — архитектура,
решения и подробные результаты подэтапов 060.28.0060.28.8;
- [Build 060.27 Engineering Migration Report](build_060_27.md) —
Persistent Market Data Storage;
- [Dzentra Target Architecture](../architecture/dzentra_target_architecture.md) —
место Market Data Acquisition в целевой архитектуре Dzentra;
- [Master Roadmap](../roadmap/master-roadmap.md) — дальнейшая
последовательность Build.
---
## 1. Назначение Build
Build 060.28 сделал operational checkpoint Trade Stream постоянным и
добавил восстановление Runtime после перезапуска процесса.
PostgreSQL Canonical Trades остаются источником рыночных фактов.
Persistent checkpoint хранит только подтверждённую точку в этой истории
и позволяет восстановить bounded deduplication window до подключения к
бирже.
Итоговая последовательность запуска:
```text
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` до запуска сети:
1. загружает и проверяет persistent checkpoint;
2. восстанавливает bounded rollover-aware Trade tail;
3. создаёт временные `TradeStreamState`;
4. атомарно публикует весь набор в общий 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
сохраняет порядок:
```text
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 используют единый порядок блокировок:
```text
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:
```text
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](build_060_29.md), Market Data Access and
Replay.