224 lines
9.4 KiB
Markdown
224 lines
9.4 KiB
Markdown
# Build 060.26 — Integration and Regression
|
||
|
||
**Engineering Migration Report**
|
||
|
||
---
|
||
|
||
## Контроль документа
|
||
|
||
| Свойство | Значение |
|
||
|---|---|
|
||
| Build | 060.26 |
|
||
| Статус | Completed |
|
||
| Подсистема | Market Data Acquisition |
|
||
| Компонент | Trades Feed / Trade Stream Runtime |
|
||
| Дата завершения | 2026-07-31 |
|
||
| Версия | 1.0 |
|
||
|
||
---
|
||
|
||
## Связанные документы
|
||
|
||
- [Build 060.25 Engineering Migration Report](build_060_25.md) — итог
|
||
Production Runtime Integration;
|
||
- [Build 060.26 Architecture](build_060_26_architecture.md) — архитектура,
|
||
решения и подробные результаты подэтапов 060.26.0–060.26.6;
|
||
- [Dzentra Target Architecture](../architecture/dzentra_target_architecture.md) —
|
||
место Trade Stream в целевой архитектуре Dzentra;
|
||
- [Master Roadmap](../roadmap/master-roadmap.md) — дальнейшая
|
||
последовательность Build.
|
||
|
||
---
|
||
|
||
## 1. Назначение Build
|
||
|
||
Build 060.25 собрал Production Trade Stream Runtime и проверил его на
|
||
детерминированных in-process boundaries. Цель Build 060.26 — проверить
|
||
тот же production graph через реальные сетевые границы и длительный
|
||
lifecycle:
|
||
|
||
```text
|
||
production factory
|
||
→ local/live WebSocket connection
|
||
→ subscription and ACK
|
||
→ Live Trade processing
|
||
→ network fault
|
||
→ single-flight reconnect
|
||
→ subscription restore
|
||
→ REST Recovery
|
||
→ buffered Live processing
|
||
→ continued Runtime
|
||
→ graceful shutdown without leaks
|
||
```
|
||
|
||
Build выполнялся по verification-first правилу: production-код мог
|
||
изменяться только при обнаружении реального дефекта проверочным
|
||
сценарием.
|
||
|
||
---
|
||
|
||
## 2. Завершённые подэтапы
|
||
|
||
| Подэтап | Название | Статус |
|
||
|---|---|---|
|
||
| 060.26.0 | Verification Contract and Test Taxonomy | Accepted |
|
||
| 060.26.1 | Loopback Network Harness | Accepted |
|
||
| 060.26.2 | Reconnect and Recovery Integration | Accepted |
|
||
| 060.26.3 | Fault, Cancellation and Resource Verification | Accepted |
|
||
| 060.26.4 | Stress and Soak Verification | Accepted |
|
||
| 060.26.5 | Opt-in Dzengi Live Verification | Accepted |
|
||
| 060.26.6 | Final Regression and Acceptance | Accepted |
|
||
|
||
Каждая группа проходила отдельный read-only review. Обнаруженные
|
||
findings исправлялись и закрывались regression-тестами до принятия.
|
||
|
||
---
|
||
|
||
## 3. Test taxonomy и сетевой стенд
|
||
|
||
В pytest зарегистрированы три явных набора:
|
||
|
||
- `integration` — настоящие локальные TCP, WebSocket и HTTP соединения;
|
||
- `stress` — локальная нагрузка, reconnect storm и soak;
|
||
- `live` — только явная opt-in проверка публичных Dzengi endpoints.
|
||
|
||
Обычная регрессия исключает все три набора. Поэтому локальная сеть,
|
||
длительные тесты и внешний exchange не запускаются неявно.
|
||
|
||
Loopback harness использует production WebSocket transport и REST
|
||
client. Он умеет выполнять graceful close, TCP abort, client-to-server
|
||
blackhole, HTTP delay/error и invalid WebSocket message, а также ведёт
|
||
точные счётчики соединений, handlers, relay tasks, stream writers и
|
||
HTTP server thread.
|
||
|
||
---
|
||
|
||
## 4. Проверенные гарантии Runtime
|
||
|
||
Интеграционные сценарии подтвердили:
|
||
|
||
1. subscription restore происходит до REST Recovery;
|
||
2. recovered Trades обрабатываются до buffered live Trades;
|
||
3. receive failure и Ping timeout используют одну reconnect generation;
|
||
4. graceful close, TCP abort и последовательные reconnect не создают
|
||
конкурирующих операций;
|
||
5. HTTP error и invalid message завершают Runtime предсказуемо;
|
||
6. cancellation ожидает завершения блокирующего REST worker;
|
||
7. ошибка cleanup не скрывает primary Runtime error;
|
||
8. partial startup не оставляет запущенных задач и серверов;
|
||
9. после завершения отсутствуют owned Runtime и harness resources.
|
||
|
||
---
|
||
|
||
## 5. Stress и soak
|
||
|
||
Fixed stress проверяет:
|
||
|
||
- 20 000 последовательных Trades;
|
||
- точный ordering и итоговый checkpoint;
|
||
- ограничение deduplication window до 10 000 записей;
|
||
- ненулевой memory baseline;
|
||
- остаточный рост памяти после прогрева не более 4 MiB;
|
||
- 30 reconnect generations с чередованием close, abort и Ping timeout.
|
||
|
||
Стандартный soak выполняется 120 секунд и обрабатывает 6 000 Trades с
|
||
24 reconnect. Финальный расширенный soak выполнялся 900 секунд и
|
||
обработал 45 000 Trades со 180 reconnect в одном Runtime lifecycle.
|
||
|
||
---
|
||
|
||
## 6. Live verification и обнаруженные дефекты
|
||
|
||
Opt-in live harness использует только публичные market-data операции,
|
||
явные HTTPS/WSS URL и один явно заданный symbol. Он не использует API
|
||
credentials, Telegram, database или торговые операции.
|
||
|
||
Live-проверка подтвердила production sequence:
|
||
|
||
```text
|
||
Live Trade
|
||
→ checkpoint
|
||
→ reconnect
|
||
→ subscription restore
|
||
→ REST Recovery
|
||
→ новая Live Trade
|
||
→ graceful stop
|
||
```
|
||
|
||
Первый live-запуск выявил, что Dzengi Trade ID является signed 32-bit
|
||
значением. Повторный запуск выявил одну и ту же биржевую сделку через
|
||
WebSocket и REST с различным transport `source`.
|
||
|
||
Реальные дефекты исправлены единым контрактом:
|
||
|
||
- WebSocket и REST принимают полный signed 32-bit диапазон;
|
||
- `INT32_MAX → INT32_MIN` и `-1 → 0` являются продвижением ID;
|
||
- расстояние ровно в половину цикла отклоняется как неоднозначное;
|
||
- Consistency и Recovery используют один rollover-aware порядок;
|
||
- identity биржевой сделки не зависит от transport `source`, но
|
||
различие цены, количества, времени или стороны остаётся ошибкой.
|
||
|
||
Проверка также подтвердила HTTP 200 и одинаковую структуру ответа
|
||
`/api/v1/aggTrades` и `/api/v2/aggTrades` для
|
||
`BTC/USD_LEVERAGE`. Production Recovery сохраняет текущий endpoint
|
||
`/api/v1/aggTrades`.
|
||
|
||
---
|
||
|
||
## 7. Финальные результаты
|
||
|
||
Итоговая приёмка выполнена 2026-07-31:
|
||
|
||
```text
|
||
Rollover/Recovery target: 401 passed
|
||
Integration repeated ten times: 110 passed
|
||
Fixed stress target: 3 passed, 1 deselected in 6.81s
|
||
Standard 120-second soak: 1 passed, 3 deselected in 120.09s
|
||
Extended 900-second soak: 1 passed, 3 deselected in 900.11s
|
||
Full offline regression: 1930 passed, 16 deselected in 3.64s
|
||
Opt-in Dzengi live verification: 1 passed in 140.42s
|
||
git diff --check: clean
|
||
```
|
||
|
||
В integration, stress и soak прогонах `ResourceWarning` считался
|
||
ошибкой. После каждого сценария подтверждалось отсутствие оставшихся
|
||
Runtime tasks, WebSocket/TCP handlers, relay tasks, tracked writers и
|
||
HTTP server threads.
|
||
|
||
---
|
||
|
||
## 8. Границы Build
|
||
|
||
Build 060.26 не реализует:
|
||
|
||
- persistent Market Data Storage;
|
||
- persistent checkpoint;
|
||
- startup recovery после перезапуска процесса;
|
||
- Historical Queries;
|
||
- Replay API;
|
||
- Analytics API;
|
||
- новый reconnect retry/backoff policy.
|
||
|
||
Эти задачи относятся к Build 060.27–060.29. Полная итоговая ревизия
|
||
документации подсистемы остаётся задачей Build 060.30.
|
||
|
||
Постороннее пользовательское изменение `.gitignore` не относится к
|
||
Build 060.26 и не должно включаться в его staging.
|
||
|
||
---
|
||
|
||
## 9. Итог
|
||
|
||
Build 060.26 завершён.
|
||
|
||
Production Trade Stream Runtime проверен через настоящие локальные
|
||
сетевые соединения, управляемые faults, длительные reconnect/recovery
|
||
циклы и ограниченный live Dzengi scenario. Финальный read-only review
|
||
не выявил незакрытых findings, а стандартный и расширенный soak не
|
||
обнаружили утечек задач, сокетов, потоков или памяти сверх принятого
|
||
порога.
|
||
|
||
Следующий этап — [Build 060.27](build_060_27.md), посвящённый
|
||
долговременному хранению Trades и формированию Persistent Market Data
|
||
Storage.
|