14 KiB
Build 060.25 — Production Runtime Integration
Engineering Migration Report
Контроль документа
| Свойство | Значение |
|---|---|
| Build | 060.25 |
| Статус | Completed |
| Подсистема | Market Data Acquisition |
| Компонент | Trades Feed / Trade Stream Runtime |
| Дата завершения | 2026-07-31 |
| Версия | 1.0 |
Связанные документы
- Build 060.24 Engineering Migration Report — итог внутренней Runtime Recovery Architecture;
- Build 060.24 Architecture — архитектурные границы Recovery Runtime;
- Build 060.25 Architecture — полная спецификация Production Runtime Integration и принятые ADR;
- Dzentra Target Architecture — место Trade Stream в целевой архитектуре Dzentra;
- Master Roadmap — дальнейшая последовательность Build.
1. Назначение Build
Build 060.24 создал внутренний граф компонентов Trade Stream Runtime, но не подключал его к реальному жизненному циклу приложения.
Цель Build 060.25 — превратить этот граф в один управляемый production Runtime:
Application Bootstrap
│
▼
Production Trade Stream Factory
│
▼
WebSocket connect and subscribe
│
▼
Trade receive loop
│
├── ACK / control routing
├── Canonical Trade pipeline
├── Consistency checkpoint
└── Runtime Events
│
▼
Heartbeat / Supervisor / Scheduler
│
▼
reconnect → subscription restore → recovery
│
▼
resume buffered live processing
Build сохраняет границы Transport, Acquisition, Consistency, Recovery и Runtime. Внешний WebSocket документ становится Canonical Trade только после прохождения существующего Acquisition pipeline.
2. Завершённые подэтапы
| Подэтап | Название | Статус |
|---|---|---|
| 060.25.0 | Static Contract Cleanup | Accepted |
| 060.25.1 | Dzengi WebSocket Transport | Accepted |
| 060.25.2 | WebSocket Session and Subscription Manager | Accepted |
| 060.25.3 | Async Runtime Event Publisher | Accepted |
| 060.25.4 | Trade Stream Production Runtime | Accepted |
| 060.25.5 | Reconnect and Recovery Integration | Accepted |
| 060.25.6 | Heartbeat and Scheduler Integration | Accepted |
| 060.25.7 | Settings, Bootstrap and Graceful Shutdown | Accepted |
| 060.25.8 | Targeted Runtime Verification | Accepted |
Каждый подэтап прошёл отдельный архитектурный review. Обнаруженные findings исправлялись до принятия соответствующего этапа.
3. Итоговая ответственность компонентов
DzengiWebSocketTransport
- открывает и закрывает WebSocket connection;
- отправляет и получает только
str | bytes; - выполняет конечный Ping/Pong liveness probe;
- не знает JSON, Trade, подписки и Recovery;
- использует отключённый встроенный WebSocket keepalive.
WebSocketSession
- идемпотентно запускает и останавливает Transport;
- повторный
start()не заменяет исправное OPEN-соединение; - принудительная замена выполняется только явным reconnect.
WebSocketSubscriptionManager
- разделяет желаемые и фактически активные подписки;
- сохраняет намерение подписаться после временной ошибки send;
- восстанавливает подписки после reconnect;
- не имитирует неподдерживаемый Dzengi unsubscribe.
Async Runtime Event Publisher
- последовательно и с
awaitдоставляет событие всем Consumer; - не создаёт скрытых background tasks;
- изолирует обычную ошибку Consumer от Runtime lifecycle;
- распространяет cancellation;
- защищён от прямой и child-task reentrancy;
- не включает чувствительный payload в аварийную диагностику.
TradeStreamProductionRuntime
- является единственным владельцем startup, receive и Scheduler tasks;
- маршрутизирует control и market сообщения;
- передаёт Trade document в общий Acquisition/Consistency pipeline;
- связывает transport failure с reconnect и Recovery;
- выполняет полный cleanup при остановке, ошибке и cancellation.
RuntimeReconnectRecoveryCoordinator
- обеспечивает single-flight для одного поколения соединения;
- закрывает общий live-processing gate;
- выполняет reconnect;
- восстанавливает подписки;
- запускает REST Recovery вне event loop;
- открывает live processing только после завершения Recovery;
- оставляет gate в failed state после terminal Recovery error.
Heartbeat, Supervisor и Scheduler
- используют состояние Transport, а не частоту рыночных сделок;
- выполняют Ping/Pong с конечным timeout;
- объединяют одновременные heartbeat и receive failures в одну reconnect/recovery operation;
- создают ровно одну Scheduler task;
- останавливаются в порядке Scheduler → Supervisor → receive loop.
Application Runner
- владеет Telegram polling и опциональным Trade Stream Runtime;
- считает ошибку включённого Trade Stream фатальной;
- ожидает завершение обеих корневых задач;
- не позволяет повторной cancellation прервать cleanup;
- закрывает Bot session ровно один раз.
4. Production lifecycle
Запуск
load settings
↓
feature flag disabled
└── Runtime graph не создаётся
feature flag enabled
↓
build concrete dependency graph
↓
start WebSocket session
↓
send Trade subscription
↓
start Supervisor
↓
start receive loop and Scheduler
Фабрика только собирает граф зависимостей. Сетевые действия начинаются
только из TradeStreamProductionRuntime.run().
Reconnect и Recovery
transport failure or failed liveness probe
↓
capture connection generation
↓
acquire single-flight operation
↓
close live-processing gate
↓
disconnect old connection
↓
connect new connection
↓
restore desired subscriptions
↓
recover missing Trades through REST
↓
process buffered live Trades
Recovery и live processing используют один экземпляр Consistency Layer и не изменяют checkpoint параллельно.
Остановка
stop Scheduler
↓
await Scheduler task
↓
stop Supervisor
↓
cancel and await receive loop
↓
stop WebSocket session
↓
clear subscriptions
↓
close Bot session at Application boundary
5. Конфигурация
Trade Stream управляется отдельным безопасным feature flag:
TRADE_STREAM_ENABLED
При включённом Runtime обязательны явные:
- WebSocket URL;
- список символов;
- transport timeouts;
- heartbeat timeout;
- Scheduler interval;
- максимальный размер Recovery Window.
Legacy WebSocket URL и default_symbol не используются как fallback.
Наличие EXCHANGE_ENABLED само по себе не включает Trade Stream.
6. Ключевые архитектурные гарантии
После Build 060.25 выполняются следующие правила:
exactly one production receive loop
exactly one scheduler task
at most one reconnect/recovery sequence per generation
reconnect =
disconnect
→ connect
→ restore subscriptions
recovery precedes buffered live processing
disabled Trade Stream creates no Runtime graph
construction has no network side effects
all owned tasks are cancelled or completed and awaited
7. Реализованные файлы
Добавленные production-файлы
app/src/bootstrap/
application.py
trade_stream_runtime.py
app/src/market_data/acquisition/adapters/dzengi/
websocket_control_message_handler.py
websocket_inbound_message_classifier.py
websocket_transport.py
app/src/market_data/acquisition/runtime/
acquisition_runtime_event_logging_consumer.py
acquisition_runtime_event_publisher.py
live_processing_gate.py
runtime_liveness_probe.py
runtime_reconnect_recovery_coordinator.py
trade_stream_production_runtime.py
websocket_inbound_message.py
websocket_session.py
websocket_subscription_manager.py
Изменённые production-файлы
app/.env.example
app/src/bootstrap/app_factory.py
app/src/core/config.py
app/src/integrations/exchange/rest_client.py
app/src/main.py
app/src/market_data/acquisition/exceptions.py
app/src/market_data/acquisition/runtime/reconnect.py
app/src/market_data/acquisition/runtime/scheduler.py
app/src/market_data/acquisition/runtime/supervisor.py
app/src/market_data/acquisition/trade_stream_runtime_composition.py
Тесты
Добавлено или расширено покрытие:
app/tests/unit/bootstrap/
app/tests/unit/core/
app/tests/unit/market_data/acquisition/adapters/dzengi/
app/tests/unit/market_data/acquisition/runtime/
app/tests/unit/market_data/acquisition/
app/tests/unit/test_main.py
Постороннее пользовательское изменение .gitignore не относится к
Build 060.25.
8. Targeted Runtime Verification
060.25.8 добавил только тестовый код и не менял production-поведение.
Через реальную production factory и реальные компоненты Runtime graph, но с управляемыми WebSocket и REST boundaries, проверены:
- выключенный feature flag не создаёт Runtime graph;
- subscribe → ACK → Trade обновляет общий checkpoint;
- ошибка connect фатальна и не оставляет задач;
- ошибка первой subscription send полностью откатывает startup;
- reconnect заменяет connection и восстанавливает подписку до Recovery;
- recovered Trade обрабатывается раньше buffered live Trade;
- Recovery error запрещает обработку buffered live Trade;
- одновременные ошибки корневых задач наблюдаются детерминированно;
- повторная cancellation не прерывает cleanup;
- Bot session закрывается один раз, owned tasks всегда await-ятся.
Итоговый read-only review 060.25.8 новых findings не выявил.
9. Результаты тестирования
Повторная проверка выполнена 2026-07-31:
Expanded Production Runtime target: 445 passed
Full project regression: 1869 passed
Тесты не используют реальную сеть, production credentials или недетерминированные внешние задержки.
10. Что не входит в Build
Build 060.25 не реализует:
- длительные live exchange и network fault scenarios;
- production stress certification;
- persistent market data storage;
- persistent checkpoint;
- startup recovery после перезапуска процесса;
- historical query и Replay API;
- аналитические вычисления поверх исторических данных.
Эти задачи относятся к следующим Build и зафиксированы в
master-roadmap.md.
11. Итог
Build 060.25 завершён.
Trade Stream подключён к bootstrap приложения как отдельный, отключённый по умолчанию production Runtime. Он управляет реальным WebSocket lifecycle, восстанавливает подписки и пропущенные сделки, сохраняет порядок Recovery и Live processing и детерминированно освобождает принадлежащие ему ресурсы.
Следующий этап — Build 060.26, посвящённый интеграционным, fault, reconnect, recovery и stress-сценариям за пределами детерминированного in-process unit harness.