Build 060.28: implement Persistent Checkpoint and Startup Recovery
This commit is contained in:
244
docs/migrations/build_060_28.md
Normal file
244
docs/migrations/build_060_28.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# 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.md` — архитектура, решения и подробные
|
||||
результаты подэтапов 060.28.0–060.28.8;
|
||||
- `build_060_27.md` — Persistent Market Data Storage;
|
||||
- `dzentra_target_architecture.md` — место Market Data Acquisition в
|
||||
целевой архитектуре Dzentra;
|
||||
- `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, Market Data Access and Replay.
|
||||
851
docs/migrations/build_060_28_architecture.md
Normal file
851
docs/migrations/build_060_28_architecture.md
Normal file
@@ -0,0 +1,851 @@
|
||||
# Build 060.28 — Persistent Checkpoint and Startup Recovery Architecture
|
||||
|
||||
**Статус:** Completed
|
||||
|
||||
**Build:** 060.28
|
||||
|
||||
**Подсистема:** Market Data Acquisition / Persistent Checkpoint
|
||||
|
||||
**Дата начала:** 2026-08-01
|
||||
|
||||
**Дата завершения:** 2026-08-01
|
||||
|
||||
**Версия документа:** 1.14
|
||||
|
||||
---
|
||||
|
||||
## 1. Назначение
|
||||
|
||||
Build 060.28 сохраняет operational checkpoint Trade Stream в
|
||||
PostgreSQL и восстанавливает Runtime после перезапуска процесса.
|
||||
|
||||
Build использует Canonical Trade history, созданную в 060.27, как более
|
||||
достоверный источник рыночных фактов. Persistent checkpoint является
|
||||
операционным указателем на подтверждённую строку истории и не заменяет
|
||||
Market Data Storage.
|
||||
|
||||
После завершения Build новый процесс должен:
|
||||
|
||||
1. проверить persistent checkpoint по durable Trade history;
|
||||
2. восстановить checkpoint и deduplication window в Consistency Layer;
|
||||
3. подключить WebSocket и подтвердить подписку;
|
||||
4. восстановить Trades за время остановки через REST;
|
||||
5. только затем продолжить обработку накопленных Live сообщений.
|
||||
|
||||
---
|
||||
|
||||
## 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 |
|
||||
|
||||
060.28.0 зафиксировал immutable `PersistentTradeCheckpoint`, узкий
|
||||
runtime-checkable `TradeCheckpointStorageProtocol` и специализированные
|
||||
checkpoint conflict/integrity errors. Контракты не импортируют Runtime,
|
||||
Recovery, Bootstrap или PostgreSQL implementation.
|
||||
|
||||
060.28.1 добавил versioned migration 8 с непартиционированной таблицей
|
||||
`market_data.trade_stream_checkpoints`. Реальный PostgreSQL подтвердил
|
||||
структуру колонок, idempotent migration history, точный foreign key и
|
||||
запрет orphan/delete для активной checkpoint Trade.
|
||||
|
||||
Оба подэтапа приняты после отдельного read-only review и реальной
|
||||
PostgreSQL-проверки. Они реализованы без checkpoint repository,
|
||||
Consistency integration, Runtime wiring, Bootstrap I/O и изменения
|
||||
feature flags.
|
||||
|
||||
060.28.2 расширил существующий `PostgresTradeRepository`: он остаётся
|
||||
единственным владельцем записи Canonical Trades и одновременно
|
||||
реализует `TradeCheckpointStorageProtocol`. Trade write, checkpoint
|
||||
lock, expected-identity CAS и revision update выполняются через одно
|
||||
соединение и одну transaction. Repository распознаёт уже
|
||||
зафиксированную candidate Trade как безопасный повтор, восстанавливает
|
||||
bounded rollover-aware tails и явно отклоняет stale/ambiguous writer.
|
||||
|
||||
Подэтап принят после отдельного read-only review и исправления двух
|
||||
rollover-tail findings. Durable acceptance anchor использует
|
||||
`first_observed_at`, а повторившийся raw Trade ID выбирается только из
|
||||
последнего цикла не позже exact checkpoint Trade. Consistency, Runtime,
|
||||
Bootstrap и feature flags не изменялись.
|
||||
|
||||
060.28.3 разделил persistence-вызовы по уже принятому решению
|
||||
Consistency Layer. Новая Trade передаётся в атомарный
|
||||
`store_trade_and_advance_checkpoint` вместе с точной предыдущей
|
||||
`last_trade`, а полный дубликат вызывает только `store_trade` для
|
||||
обновления provenance. Storage не повторяет rollover-классификацию.
|
||||
Ошибка любой ветви распространяется вызывающему коду; новая Trade не
|
||||
попадает в in-memory state до успешного PostgreSQL commit.
|
||||
|
||||
Подэтап реализован без hydration, Startup Recovery, новых feature flags,
|
||||
изменения Bootstrap/settings или lifecycle. Отдельный приёмочный
|
||||
read-only review подтвердил границы ответственности, порядок durable
|
||||
commit → in-memory checkpoint и полный rollback при CAS-конфликте;
|
||||
findings не выявлено, подэтап принят.
|
||||
|
||||
060.28.4 добавил строгую фабрику `TradeStreamState.from_history`,
|
||||
одноразовую атомарную публикацию через `TradeStreamStateStore.initialize`
|
||||
и отдельный `TradeStreamStateHydrator`. Hydrator сначала полностью
|
||||
готовит состояния всех символов и только затем публикует их в общий
|
||||
Store; при ошибке ни один частично собранный state не становится
|
||||
доступен Runtime.
|
||||
|
||||
Для перехода с Build 060.27 storage-контракт получил отдельную операцию
|
||||
`adopt_existing_trade_as_checkpoint`. Она создаёт revision `1` на уже
|
||||
существующей durable Trade, не выполняет повторную запись наблюдения и
|
||||
не меняет `source`, provenance, `first_observed_at` или
|
||||
`last_observed_at`. После adoption Hydrator повторно загружает tail уже
|
||||
от окончательной persistent-точки и заново проверяет его. Подэтап
|
||||
реализован без подключения к Bootstrap, Runtime lifecycle и Startup
|
||||
Recovery. Приёмочный review выявил один случай, когда ложный non-tuple
|
||||
ответ Storage мог быть принят за пустую историю. После исправления
|
||||
только `tuple()` означает отсутствие истории, а `None` и `[]` приводят
|
||||
к фатальной integrity-ошибке без публикации state. Повторный review
|
||||
findings не выявил; подэтап принят.
|
||||
|
||||
060.28.5 добавил отдельный `RuntimeStartupRecoveryCoordinator` и
|
||||
встроил persistent startup-путь в `TradeStreamProductionRuntime`.
|
||||
Hydration выполняется до сетевого подключения. После подписки Runtime
|
||||
одним consumer ожидает положительный ACK, сохраняет ранние Live
|
||||
документы в ограниченный FIFO, выполняет REST Recovery при закрытом
|
||||
общем gate и только затем обрабатывает накопленный Live-поток.
|
||||
|
||||
Первый приёмочный review выявил расхождение регистра между Hydrator и
|
||||
Startup Recovery, способное бесшумно пропустить восстановление для
|
||||
lowercase-конфигурации. Все Runtime-границы и Hydrator переведены на
|
||||
единый `normalize_symbol`; варианты одного символа в разном регистре
|
||||
схлопываются до запуска blocking worker. Regression-тест проходит
|
||||
полную цепочку Hydration → exact-key State Store → REST Recovery.
|
||||
Повторный независимый review findings не выявил; подэтап принят без
|
||||
изменения Bootstrap и settings.
|
||||
|
||||
060.28.6 подключил persistent checkpoint к Production Bootstrap без
|
||||
нового feature flag. При включённом Market Data Storage один экземпляр
|
||||
`PostgresTradeRepository` одновременно используется как владелец
|
||||
durable Trades и checkpoint storage, а Runtime получает созданный
|
||||
Composition `RuntimeStartupRecoveryCoordinator`. Неполный persistent-
|
||||
граф отклоняется до создания WebSocket/REST-компонентов.
|
||||
|
||||
Настройки ACK timeout и вместимости стартового FIFO получили строгую
|
||||
валидацию и явные environment-параметры. Сборка приложения по-прежнему
|
||||
не открывает PostgreSQL, не выполняет migrations, Hydration или Recovery
|
||||
и не создаёт фоновых задач. Application сохраняет порядок pool open +
|
||||
migrations → Runtime и Runtime stop + ожидание workers → pool close.
|
||||
После исправления устаревшего PostgreSQL integration harness повторный
|
||||
read-only review findings не выявил; подэтап принят.
|
||||
|
||||
060.28.7 добавил opt-in проверку полного Application lifecycle на
|
||||
одноразовом PostgreSQL 16: перезапуск на той же durable history,
|
||||
first-adoption истории без checkpoint, откат незавершённой transaction,
|
||||
повтор после ошибки persistence и cancellation во время blocking I/O.
|
||||
Все сценарии используют только явно заданную локальную тестовую базу и
|
||||
проверяют отсутствие оставшихся соединений, задач и обработчиков.
|
||||
|
||||
Первый приёмочный review выявил недостаточно строгую проверку порядка:
|
||||
исходные restart-сценарии наблюдали восстановленное состояние только к
|
||||
моменту подписки. Два детерминированных regression-сценария теперь
|
||||
останавливают соответственно `load_checkpoint` и
|
||||
`adopt_existing_trade_as_checkpoint` внутри storage-вызова и до снятия
|
||||
barrier подтверждают отсутствие WebSocket/REST I/O. После исправления
|
||||
два независимых read-only review findings не выявили; production-код не
|
||||
изменялся, подэтап принят.
|
||||
|
||||
060.28.8 выполнил verification-only матрицу всего Build: десятикратный
|
||||
прогон restart/failure-сценариев, полный PostgreSQL Storage и общий
|
||||
integration-наборы, opt-out isolation, fixed stress и полную стандартную
|
||||
регрессию. Итоговый review выявил один потенциальный PostgreSQL deadlock
|
||||
между Partition Manager и атомарным Trade/checkpoint writer.
|
||||
|
||||
Partition Manager переведён на единый порядок блокировок parent Trades →
|
||||
default partition → checkpoint table. Детерминированный PostgreSQL-тест
|
||||
подтвердил реальное участие обоих конкурентных callers и отсутствие
|
||||
deadlock; сценарий стабильно прошёл десять повторов. После повторения
|
||||
всей приёмочной матрицы итоговый review findings не выявил. Подэтап и
|
||||
Build 060.28 приняты.
|
||||
|
||||
---
|
||||
|
||||
## 3. Исходные инварианты
|
||||
|
||||
Build продолжает принятые решения 060.24–060.27:
|
||||
|
||||
1. Operational checkpoint принадлежит только
|
||||
`TradeStreamState.last_trade`.
|
||||
2. Live и Recovery используют один `TradeStreamStateStore` и один
|
||||
`TradeStreamConsistencyController`.
|
||||
3. Canonical Trade сохраняется до продвижения in-memory checkpoint.
|
||||
4. Ошибка включённого persistent storage является фатальной.
|
||||
5. Идентичность durable Trade равна
|
||||
`(venue, symbol, trade_id, executed_at)`.
|
||||
6. Порядок Trade ID использует единый signed 32-bit rollover-aware
|
||||
контракт.
|
||||
7. PostgreSQL pool открывается до Runtime и закрывается только после
|
||||
полной остановки Runtime.
|
||||
8. Composition не выполняет I/O и не создаёт фоновых задач.
|
||||
|
||||
---
|
||||
|
||||
## 4. Иерархия достоверности
|
||||
|
||||
```text
|
||||
PostgreSQL Canonical Trades
|
||||
│ подтверждённые рыночные факты
|
||||
▼
|
||||
Persistent Trade Stream Checkpoint
|
||||
│ операционный указатель
|
||||
▼
|
||||
TradeStreamState
|
||||
│ оперативное состояние процесса
|
||||
▼
|
||||
Live / Recovery processing
|
||||
```
|
||||
|
||||
Persistent checkpoint нельзя использовать, если соответствующая
|
||||
Canonical Trade отсутствует или отличается от durable history.
|
||||
|
||||
Checkpoint не хранит независимую копию цены, количества, стороны и
|
||||
source. Он хранит точную identity Trade. Checkpoint Service получает
|
||||
полный Canonical `Trade` соединением checkpoint с `market_data.trades`.
|
||||
|
||||
---
|
||||
|
||||
## 5. Архитектурная граница
|
||||
|
||||
```text
|
||||
Consistency Layer
|
||||
│ acquisition-side Protocol
|
||||
▼
|
||||
Checkpoint Service
|
||||
│ storage contracts
|
||||
▼
|
||||
PostgreSQL checkpoint repository
|
||||
│ общий managed pool
|
||||
▼
|
||||
market_data.trade_stream_checkpoints
|
||||
│ exact durable identity
|
||||
▼
|
||||
market_data.trades
|
||||
```
|
||||
|
||||
Consistency, Recovery и Runtime не импортируют `psycopg`, PostgreSQL
|
||||
repository или pool. PostgreSQL implementation зависит от Canonical
|
||||
Models и storage contracts, но не от Runtime lifecycle.
|
||||
|
||||
Общий `MarketDataStorage` остаётся write-only фасадом Trades, Quotes и
|
||||
Candles. Узкие checkpoint reads не превращаются в Historical Query API;
|
||||
общий Data Access Layer относится к Build 060.29.
|
||||
|
||||
---
|
||||
|
||||
## 6. Storage contracts
|
||||
|
||||
### 6.1. PersistentTradeCheckpoint
|
||||
|
||||
Неизменяемый результат чтения checkpoint содержит:
|
||||
|
||||
```text
|
||||
PersistentTradeCheckpoint
|
||||
├── venue: str
|
||||
├── trade: Trade
|
||||
├── revision: int
|
||||
├── updated_at: timezone-aware datetime
|
||||
└── checkpoint_schema_version: int
|
||||
```
|
||||
|
||||
Полный `Trade` уже проверен по durable history и является checkpoint,
|
||||
который можно установить в Consistency state.
|
||||
|
||||
### 6.2. TradeCheckpointStorageProtocol
|
||||
|
||||
Узкий storage-контракт предусматривает:
|
||||
|
||||
```text
|
||||
load_checkpoint(venue, symbol)
|
||||
load_checkpoint_tail(venue, checkpoint, limit)
|
||||
load_latest_trade_tail(venue, symbol, limit)
|
||||
adopt_existing_trade_as_checkpoint(venue, trade)
|
||||
store_trade_and_advance_checkpoint(
|
||||
venue,
|
||||
expected_trade,
|
||||
trade,
|
||||
observed_at,
|
||||
)
|
||||
```
|
||||
|
||||
Назначение операций:
|
||||
|
||||
- `load_checkpoint` возвращает только подтверждённый полный checkpoint;
|
||||
- `load_checkpoint_tail` загружает bounded history для восстановления
|
||||
deduplication window;
|
||||
- `load_latest_trade_tail` используется только при первой инициализации
|
||||
после Build 060.27, если история существует, а checkpoint ещё нет;
|
||||
- `adopt_existing_trade_as_checkpoint` создаёт первый checkpoint на
|
||||
точной уже существующей durable Trade без повторной записи Trade;
|
||||
- `store_trade_and_advance_checkpoint` атомарно сохраняет принятую Trade
|
||||
и продвигает persistent checkpoint.
|
||||
|
||||
Основные read/commit-операции реализованы в 060.28.2, а безопасная
|
||||
first-adoption — в 060.28.4 существующим `PostgresTradeRepository`.
|
||||
Отдельный второй writer не создаётся; общий `MarketDataStorage`
|
||||
сохраняет write-only границу, а checkpoint reads доступны только через
|
||||
узкий `TradeCheckpointStorageProtocol`.
|
||||
|
||||
---
|
||||
|
||||
## 7. PostgreSQL schema
|
||||
|
||||
Migration 8 создаёт:
|
||||
|
||||
```text
|
||||
market_data.trade_stream_checkpoints
|
||||
├── venue TEXT
|
||||
├── symbol TEXT
|
||||
├── trade_id INTEGER
|
||||
├── executed_at TIMESTAMPTZ
|
||||
├── revision BIGINT
|
||||
├── updated_at TIMESTAMPTZ
|
||||
└── checkpoint_schema_version INTEGER
|
||||
```
|
||||
|
||||
Ограничения:
|
||||
|
||||
```text
|
||||
PRIMARY KEY (venue, symbol)
|
||||
|
||||
FOREIGN KEY (venue, symbol, trade_id, executed_at)
|
||||
REFERENCES market_data.trades (
|
||||
venue,
|
||||
symbol,
|
||||
trade_id,
|
||||
executed_at
|
||||
)
|
||||
ON UPDATE NO ACTION
|
||||
ON DELETE NO ACTION
|
||||
DEFERRABLE INITIALLY DEFERRED
|
||||
```
|
||||
|
||||
Дополнительно проверяются:
|
||||
|
||||
- непустые `venue` и `symbol`;
|
||||
- signed 32-bit диапазон `trade_id`;
|
||||
- положительные `revision` и `checkpoint_schema_version`;
|
||||
- timezone semantics через PostgreSQL `TIMESTAMPTZ`.
|
||||
|
||||
Таблица не партиционируется: для `(venue, symbol)` существует ровно одна
|
||||
маленькая operational row.
|
||||
|
||||
---
|
||||
|
||||
## 8. Атомарное продвижение
|
||||
|
||||
Для новой принятой Trade `PostgresTradeRepository` выполняет:
|
||||
|
||||
```text
|
||||
BEGIN
|
||||
│
|
||||
├── store Canonical Trade
|
||||
├── lock current checkpoint row
|
||||
├── verify expected previous Trade identity
|
||||
├── advance checkpoint and revision
|
||||
└── COMMIT
|
||||
↓
|
||||
advance in-memory TradeStreamState
|
||||
```
|
||||
|
||||
Если Trade write или checkpoint update завершается ошибкой, вся
|
||||
PostgreSQL transaction откатывается, а in-memory state не изменяется.
|
||||
|
||||
Точный дубликат продолжает обновлять provenance в `market_data.trades`,
|
||||
но не продвигает persistent или in-memory checkpoint.
|
||||
|
||||
`expected_trade` защищает от stale writer. Если database checkpoint не
|
||||
равен ожидаемому предыдущему checkpoint, операция завершается явным
|
||||
конфликтом. Это защита от повреждения, а не distributed leader election.
|
||||
|
||||
---
|
||||
|
||||
## 9. Восстановление Consistency state
|
||||
|
||||
Одного `last_trade` недостаточно. После перезапуска REST Recovery может
|
||||
вернуть более старые Trades у общей временной границы. Поэтому Startup
|
||||
должен восстановить bounded deduplication tail до checkpoint.
|
||||
|
||||
Правила:
|
||||
|
||||
1. Загружается не более текущего `deduplication_window_size`.
|
||||
2. Порядок нормализуется общим rollover-aware контрактом.
|
||||
3. Проверяются symbol, Canonical payload и конечная checkpoint identity.
|
||||
4. Сначала собирается новый временный `TradeStreamState`.
|
||||
5. Store получает состояние только после полной успешной проверки.
|
||||
6. Hydration не вызывает persistence sink и не записывает provenance.
|
||||
7. Первый checkpoint на истории 060.27 создаётся только после строгой
|
||||
проверки временного state.
|
||||
8. После first-adoption tail повторно загружается относительно уже
|
||||
созданного checkpoint и проверяется заново.
|
||||
9. Все символы публикуются одним `initialize`; ошибка одного символа не
|
||||
оставляет частично заполненный State Store.
|
||||
|
||||
Обязательные границы порядка:
|
||||
|
||||
```text
|
||||
INT32_MAX → INT32_MIN
|
||||
-1 → 0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Первый запуск после Build 060.27
|
||||
|
||||
### 10.1. Нет checkpoint и нет Trades
|
||||
|
||||
Состояние остаётся пустым. REST backfill без известной начальной границы
|
||||
не выполняется. Первый принятый Live Trade создаёт первый checkpoint.
|
||||
|
||||
### 10.2. Нет checkpoint, но есть durable Trades
|
||||
|
||||
Checkpoint Service загружает bounded latest tail, проверяет его порядок
|
||||
и один раз создаёт checkpoint на последней подтверждённой Trade. Этот
|
||||
путь предназначен для перехода с завершённого Build 060.27.
|
||||
|
||||
### 10.3. Checkpoint существует
|
||||
|
||||
Checkpoint обязан ссылаться на существующую точную Canonical Trade.
|
||||
Отсутствие строки, несовпадение payload или неоднозначный rollover-order
|
||||
являются фатальной ошибкой startup. Тихий переход к пустому состоянию
|
||||
запрещён.
|
||||
|
||||
---
|
||||
|
||||
## 11. Startup Recovery sequence
|
||||
|
||||
```text
|
||||
open PostgreSQL pool
|
||||
↓
|
||||
apply migrations
|
||||
↓
|
||||
load checkpoint and deduplication tail
|
||||
↓
|
||||
hydrate TradeStreamState
|
||||
↓
|
||||
connect WebSocket
|
||||
↓
|
||||
send Trade subscription
|
||||
↓
|
||||
receive successful ACK
|
||||
↓
|
||||
capture recovery_end_time
|
||||
↓
|
||||
REST Recovery under shared live gate
|
||||
↓
|
||||
process buffered WebSocket market messages
|
||||
↓
|
||||
start normal receive / Supervisor / Scheduler lifecycle
|
||||
```
|
||||
|
||||
До завершения Recovery существует только один consumer WebSocket.
|
||||
Market messages, необходимые для получения последующего ACK, временно
|
||||
буферизуются в исходном порядке и не передаются в Consistency Layer.
|
||||
|
||||
ACK имеет конечный timeout. Negative ACK, timeout, checkpoint error или
|
||||
Recovery error являются terminal startup failure.
|
||||
|
||||
REST Recovery использует существующие `TradeRecoveryWindowPlanner`,
|
||||
`TradeRecoveryController` и общий Consistency state. При crash посреди
|
||||
Recovery следующий процесс начинает с последней атомарно сохранённой
|
||||
checkpoint Trade.
|
||||
|
||||
---
|
||||
|
||||
## 12. Retention policy
|
||||
|
||||
Retention не может удалить Trade, на которую указывает активный
|
||||
checkpoint.
|
||||
|
||||
Защита состоит из трёх уровней:
|
||||
|
||||
1. `FOREIGN KEY ... ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED`
|
||||
сохраняет ссылочную целостность и позволяет фиксировать Trade и
|
||||
checkpoint одной transaction;
|
||||
2. PostgreSQL создаёт внутренние FK-зависимости от каждой Trade
|
||||
partition, поэтому Partition Manager и Retention Service под общим
|
||||
advisory lock транзакционно снимают FK только на время переноса или
|
||||
удаления секции и восстанавливают его с тем же строгим контрактом до
|
||||
commit;
|
||||
3. повторное создание FK проверяет всю checkpoint table. Если Retention
|
||||
затронул активную checkpoint Trade, проверка завершается ошибкой и
|
||||
PostgreSQL откатывает удаление данных, registry и изменение FK.
|
||||
|
||||
Partition Manager сначала блокирует parent `market_data.trades` в
|
||||
`SHARE ROW EXCLUSIVE`, затем default Trade partition и checkpoint table.
|
||||
Этот порядок согласован с реализованной атомарной записью Trade →
|
||||
checkpoint и исключает взаимную блокировку с writer в существующей
|
||||
месячной partition.
|
||||
|
||||
Попытка удалить активную checkpoint Trade откатывает всю retention-
|
||||
операцию. Автоматическое удаление или откат checkpoint запрещены.
|
||||
|
||||
---
|
||||
|
||||
## 13. Feature flag и lifecycle
|
||||
|
||||
Отдельный checkpoint feature flag не вводится.
|
||||
|
||||
```text
|
||||
MARKET_DATA_STORAGE_ENABLED=false
|
||||
→ прежний полностью in-memory Runtime
|
||||
|
||||
MARKET_DATA_STORAGE_ENABLED=true
|
||||
→ durable Trades + Persistent Checkpoint + Startup Recovery
|
||||
```
|
||||
|
||||
Таким образом persistent checkpoint нельзя включить без durable Market
|
||||
Data. Существующий Storage flag остаётся выключенным по умолчанию.
|
||||
|
||||
Composition только строит зависимости. Checkpoint I/O начинается после
|
||||
открытия pool и migrations. Shutdown сохраняет существующий порядок:
|
||||
|
||||
```text
|
||||
Trade Runtime stop
|
||||
↓
|
||||
await all persistence/recovery workers
|
||||
↓
|
||||
PostgreSQL pool close
|
||||
```
|
||||
|
||||
Checkpoint не создаёт Scheduler, periodic flush или fire-and-forget
|
||||
задачи. Каждая принятая Trade фиксируется inline до in-memory checkpoint.
|
||||
|
||||
---
|
||||
|
||||
## 14. Ошибки и конкурентность
|
||||
|
||||
Фатальными являются:
|
||||
|
||||
- checkpoint с отсутствующей durable Trade;
|
||||
- несовпадающая checkpoint identity или Canonical payload;
|
||||
- stale expected checkpoint;
|
||||
- ошибка атомарной Trade/checkpoint transaction;
|
||||
- неоднозначный signed rollover-order;
|
||||
- неуспешная hydration;
|
||||
- ошибка Startup Recovery;
|
||||
- ACK timeout или negative ACK.
|
||||
|
||||
Повторная загрузка checkpoint является read-only и идемпотентна.
|
||||
Повтор атомарного commit после неоднозначного сетевого результата должен
|
||||
распознавать уже зафиксированную ту же candidate identity.
|
||||
|
||||
Build предполагает одного активного Trade Runtime для `(venue, symbol)`.
|
||||
Optimistic checkpoint conflict не даёт второму экземпляру незаметно
|
||||
повредить состояние. Distributed lease и автоматический failover не
|
||||
входят в scope.
|
||||
|
||||
---
|
||||
|
||||
## 15. Критерии приёмки
|
||||
|
||||
1. Storage contracts не импортируют Runtime, Recovery или Bootstrap.
|
||||
2. Checkpoint table имеет точный ключ `(venue, symbol)`.
|
||||
3. Checkpoint ссылается на durable Trade identity.
|
||||
4. Schema запрещает пустые identity fields и неверные версии.
|
||||
5. Migration остаётся versioned, атомарной и идемпотентной.
|
||||
6. Accepted Trade и checkpoint фиксируются одной transaction.
|
||||
7. Ошибка checkpoint откатывает новую Trade.
|
||||
8. Duplicate provenance не продвигает checkpoint.
|
||||
9. Stale concurrent writer получает явный conflict.
|
||||
10. Hydration восстанавливает checkpoint и deduplication tail.
|
||||
11. Rollover boundaries восстанавливаются в правильном порядке.
|
||||
12. Повреждённый persistent checkpoint не скрывается.
|
||||
13. Startup Recovery заканчивается до buffered Live processing.
|
||||
14. Cancellation ожидает уже начатые blocking workers.
|
||||
15. Retention не удаляет активную checkpoint Trade.
|
||||
16. Composition не выполняет PostgreSQL или network I/O.
|
||||
17. Runtime полностью останавливается до pool close.
|
||||
18. После тестов не остаются asyncio tasks, threads или connections.
|
||||
19. Целевые, integration и полная regression проходят успешно.
|
||||
|
||||
---
|
||||
|
||||
## 16. Test strategy
|
||||
|
||||
### Unit
|
||||
|
||||
- value object и runtime-checkable Protocol;
|
||||
- schema SQL и migration order;
|
||||
- repository load/commit/CAS и полный rollback;
|
||||
- hydration и bounded deduplication tail;
|
||||
- no-checkpoint и first-adoption policy;
|
||||
- ACK timeout, buffering, ordering и cancellation.
|
||||
|
||||
### PostgreSQL integration
|
||||
|
||||
- реальный foreign key и transactional commit;
|
||||
- concurrent first insert и stale update;
|
||||
- crash boundaries до и после commit;
|
||||
- restart с той же disposable database;
|
||||
- retention active-checkpoint protection;
|
||||
- отсутствие оставшихся pool connections.
|
||||
|
||||
### Runtime integration
|
||||
|
||||
- первый процесс сохраняет Live Trades и завершается;
|
||||
- второй процесс восстанавливает checkpoint и deduplication tail;
|
||||
- REST заполняет downtime gap;
|
||||
- buffered Live Trades обрабатываются после Recovery;
|
||||
- duplicate boundary обновляет provenance один раз;
|
||||
- failure не открывает live gate и не оставляет owned tasks.
|
||||
|
||||
---
|
||||
|
||||
## 17. Вне scope
|
||||
|
||||
- общие Historical Queries и Data Access Layer;
|
||||
- Replay API и replay clocks;
|
||||
- persistent Quotes/Candles consumers;
|
||||
- автоматический Retention Scheduler;
|
||||
- distributed runtime lease, leader election и HA failover;
|
||||
- бесконечный REST retry/backoff;
|
||||
- восстановление истории без известной durable начальной границы.
|
||||
|
||||
Эти обязанности относятся к следующим Build либо отдельным production
|
||||
инициативам.
|
||||
|
||||
---
|
||||
|
||||
## 18. Архитектурные решения
|
||||
|
||||
### ADR-060.28-001 — Durable Trades являются источником рыночных фактов
|
||||
|
||||
**Статус:** Accepted
|
||||
|
||||
Persistent checkpoint хранит identity и проверяется по Canonical Trade
|
||||
history. Он не заменяет Market Data Storage.
|
||||
|
||||
### ADR-060.28-002 — Trade и persistent checkpoint фиксируются атомарно
|
||||
|
||||
**Статус:** Accepted
|
||||
|
||||
Accepted Trade и её checkpoint принадлежат одной PostgreSQL transaction.
|
||||
In-memory checkpoint продвигается только после commit.
|
||||
|
||||
### ADR-060.28-003 — Consistency остаётся владельцем checkpoint
|
||||
|
||||
**Статус:** Accepted
|
||||
|
||||
Storage хранит operational pointer, но решение о принятии Trade и
|
||||
продвижении состояния остаётся в Consistency Layer.
|
||||
|
||||
### ADR-060.28-004 — Startup восстанавливает deduplication tail
|
||||
|
||||
**Статус:** Accepted
|
||||
|
||||
Восстановление только `last_trade` недостаточно для безопасной общей
|
||||
границы REST и Live.
|
||||
|
||||
### ADR-060.28-005 — Startup Recovery завершается до buffered Live
|
||||
|
||||
**Статус:** Accepted
|
||||
|
||||
Подписка подтверждается ACK, затем REST Recovery обрабатывается при
|
||||
закрытом общем gate и только после этого разрешаются Live Trades.
|
||||
|
||||
### ADR-060.28-006 — Retention не удаляет активную точку восстановления
|
||||
|
||||
**Статус:** Accepted
|
||||
|
||||
Удаление checkpoint Trade запрещено ссылочной целостностью. Во время
|
||||
partition maintenance Retention Service восстанавливает и повторно
|
||||
проверяет тот же FK до commit; ошибка откатывает всю transaction.
|
||||
|
||||
### ADR-060.28-007 — Отдельный checkpoint feature flag не вводится
|
||||
|
||||
**Статус:** Accepted
|
||||
|
||||
Persistent Checkpoint является частью явно включённого Market Data
|
||||
Storage и не может работать без durable Trades.
|
||||
|
||||
### ADR-060.28-008 — Optimistic conflict защищает от второго writer
|
||||
|
||||
**Статус:** Accepted
|
||||
|
||||
Checkpoint update проверяет ожидаемую previous identity. Полноценный
|
||||
distributed lease не входит в Build.
|
||||
|
||||
---
|
||||
|
||||
## 19. Verification evidence
|
||||
|
||||
Результаты реализации 060.28.0–060.28.1 на 2026-08-01:
|
||||
|
||||
```text
|
||||
Checkpoint contracts and migration unit target: 51 passed
|
||||
Expanded Storage unit target: 255 passed
|
||||
Targeted PostgreSQL schema/partition/retention: 12 passed
|
||||
Full PostgreSQL Storage integration: 20 passed
|
||||
git diff --check: clean
|
||||
```
|
||||
|
||||
PostgreSQL 16 запускался в одноразовом локальном контейнере. После
|
||||
проверки foreign key, idempotent migrations, переноса checkpoint Trade
|
||||
между default/monthly partitions и Retention rollback контейнер
|
||||
остановлен и удалён. Повторный read-only review findings не выявил.
|
||||
Checkpoint repository, Runtime и Bootstrap в этих подэтапах не
|
||||
подключались.
|
||||
|
||||
Дополнительные результаты реализации 060.28.2:
|
||||
|
||||
```text
|
||||
Checkpoint repository unit target: 69 passed
|
||||
Expanded Storage unit target: 275 passed
|
||||
Real PostgreSQL checkpoint repository target: 10 passed
|
||||
Full PostgreSQL Storage integration: 30 passed
|
||||
git diff --check: clean
|
||||
```
|
||||
|
||||
Реальный PostgreSQL подтвердил атомарный rollback Trade при checkpoint
|
||||
failure/conflict, идемпотентный повтор после commit, два конкурирующих
|
||||
первых writer, два конкурирующих CAS update и границы
|
||||
`INT32_MAX → INT32_MIN` / `-1 → 0`. PostgreSQL-контейнер после проверки
|
||||
остановлен и удалён. Consistency, Runtime и Bootstrap не изменялись.
|
||||
|
||||
Финальный review дополнительно подтвердил порядок при убывающем
|
||||
`executed_at` и растущем Trade ID, а также исключение старого полного
|
||||
32-битного цикла при повторе того же raw ID. Повторный review findings
|
||||
не выявил; 060.28.2 принят.
|
||||
|
||||
Результаты реализации 060.28.3:
|
||||
|
||||
```text
|
||||
Targeted Consistency/Storage unit: 104 passed
|
||||
Full unit regression: 2169 passed
|
||||
Targeted PostgreSQL Consistency integration: 3 passed
|
||||
Existing PostgreSQL Runtime persistence: 4 passed
|
||||
Full PostgreSQL Storage integration: 33 passed
|
||||
git diff --check: clean
|
||||
```
|
||||
|
||||
Реальный PostgreSQL подтвердил синхронное продвижение persistent и
|
||||
in-memory checkpoint, сохранение provenance дубликата без изменения
|
||||
revision и полный rollback candidate Trade при CAS-конфликте. Отдельный
|
||||
приёмочный read-only review findings не выявил; 060.28.3 принят.
|
||||
|
||||
Результаты реализации 060.28.4:
|
||||
|
||||
```text
|
||||
Targeted hydration/repository unit: 140 passed
|
||||
Full unit regression: 2209 passed
|
||||
Targeted PostgreSQL adoption/hydration: 18 passed
|
||||
Full PostgreSQL Storage integration: 41 passed
|
||||
git diff --check: clean
|
||||
```
|
||||
|
||||
Unit-тесты подтвердили strict hydration, восстановление bounded dedup
|
||||
window, атомарную публикацию нескольких символов, ошибки каждого шага и
|
||||
границы `INT32_MAX → INT32_MIN` / `-1 → 0`. Реальный PostgreSQL
|
||||
подтвердил неизменность provenance и observation timestamps при
|
||||
first-adoption, идемпотентный restart без роста revision, восстановление
|
||||
дубликатов после restart и последующее атомарное продвижение revision
|
||||
`1 → 2`. Дополнительные regression-тесты подтвердили запрет falsey
|
||||
non-tuple ответа Storage без fallback к пустому state. Повторный
|
||||
read-only review findings не выявил; 060.28.4 принят. Runtime,
|
||||
Bootstrap, settings и Startup Recovery не изменялись.
|
||||
|
||||
Результаты реализации 060.28.5:
|
||||
|
||||
```text
|
||||
Targeted Runtime/Checkpoint unit: 257 passed
|
||||
Loopback Runtime integration: 13 passed
|
||||
Critical startup ordering repeated: 10/10
|
||||
Full standard regression: 2263 passed
|
||||
Deselected integration/stress/live tests: 59
|
||||
git diff --check: clean
|
||||
```
|
||||
|
||||
Проверены Hydration до первого network I/O, положительный и ошибочный
|
||||
ACK, ограниченный FIFO ранних Live-сообщений, строгий порядок
|
||||
Recovery → buffered Live, частичный startup, cancellation blocking
|
||||
workers, cleanup owned tasks и legacy-путь без persistent checkpoint.
|
||||
Отдельные regression-сценарии подтвердили единый uppercase-ключ для
|
||||
lowercase symbols и безопасное схлопывание case-variant duplicates до
|
||||
Hydration. Два независимых повторных read-only review findings не
|
||||
выявили; 060.28.5 принят.
|
||||
|
||||
Результаты реализации 060.28.6:
|
||||
|
||||
```text
|
||||
Targeted PostgreSQL Application lifecycle: 1 passed
|
||||
Full PostgreSQL Storage integration: 41 passed
|
||||
Full integration with PostgreSQL: 54 passed
|
||||
Full standard regression: 2276 passed
|
||||
Deselected integration/stress/live tests: 59
|
||||
git diff --check: clean
|
||||
```
|
||||
|
||||
Подтверждены единый persistent dependency graph, отсутствие I/O и
|
||||
фоновых задач при Bootstrap-сборке, строгий fail-fast для неполной
|
||||
пары sink/checkpoint storage, Hydration и Startup Recovery до Live
|
||||
processing, а также закрытие PostgreSQL pool только после полной
|
||||
остановки Runtime. Повторная cancellation не прерывает cleanup.
|
||||
Исправленный реальный Application-сценарий дополнительно подтвердил
|
||||
отсутствие оставшихся owned tasks и соединений PostgreSQL. Два
|
||||
повторных read-only review findings не выявили; 060.28.6 принят.
|
||||
|
||||
Результаты реализации 060.28.7:
|
||||
|
||||
```text
|
||||
PostgreSQL test-support unit: 52 passed
|
||||
Persistent restart/failure scenarios: 9 passed
|
||||
Network-order barriers repeated: 10 x 2 passed
|
||||
Full PostgreSQL Storage integration: 50 passed
|
||||
Full integration with PostgreSQL: 63 passed
|
||||
PostgreSQL opt-out isolation: 50 skipped
|
||||
Full standard regression: 2305 passed
|
||||
Deselected integration/stress/live tests: 68
|
||||
git diff --check: clean
|
||||
```
|
||||
|
||||
Реальный PostgreSQL подтвердил восстановление checkpoint и bounded
|
||||
deduplication tail после перезапуска, безопасную first-adoption,
|
||||
атомарный rollback, повтор после persistence failure и завершение уже
|
||||
начатого blocking worker при cancellation. Два новых barrier-сценария
|
||||
отдельно доказали, что Hydration и first-adoption завершаются до первого
|
||||
WebSocket/REST I/O; каждый сценарий стабильно прошёл десять повторов.
|
||||
Opt-out запуск пропустил все 50 PostgreSQL-тестов без подключения к базе.
|
||||
Одноразовый контейнер после проверки остановлен и удалён. Финальный
|
||||
приёмочный review findings не выявил; 060.28.7 принят.
|
||||
|
||||
Финальные результаты 060.28.8 после исправления lock order:
|
||||
|
||||
```text
|
||||
Partition lock-order unit target: 21 passed
|
||||
Restart/failure scenarios repeated: 10 x 9 passed
|
||||
Partition/checkpoint race repeated: 10 x 1 passed
|
||||
Full PostgreSQL Storage integration: 51 passed
|
||||
Full integration with PostgreSQL: 64 passed
|
||||
PostgreSQL opt-out isolation: 51 skipped
|
||||
Fixed stress target: 3 passed, 1 deselected
|
||||
Full standard regression: 2305 passed
|
||||
Deselected integration/stress/live tests: 69
|
||||
git diff --check: clean
|
||||
Untracked files whitespace check: clean
|
||||
```
|
||||
|
||||
В integration и stress наборах `ResourceWarning` считался ошибкой.
|
||||
Одноразовый PostgreSQL 16 после проверки остановлен и удалён. Итоговый
|
||||
review полного Build подтвердил архитектурные границы, атомарность,
|
||||
CAS/rollover, Startup Recovery, lifecycle/cancellation, Retention и
|
||||
единый порядок блокировок; открытых findings не осталось.
|
||||
|
||||
---
|
||||
|
||||
## 20. Следующий Build
|
||||
|
||||
Build 060.28 завершён и принят. Следующий этап — Build 060.29, Market
|
||||
Data Access and Replay.
|
||||
Reference in New Issue
Block a user