Files
dzentra_bot/docs/migrations/build_060_21_architecture.md

931 lines
26 KiB
Markdown
Raw 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.21 — Runtime Integration Contracts
## Архитектурное обоснование
---
# Назначение документа
Данный документ фиксирует архитектурные решения, принимаемые перед началом реализации **Build 060.21 — Runtime Protocol Integration**.
Build 060.20.1 завершил важнейший этап архитектурной декомпозиции подсистемы **Trades Feed**.
В результате архитектурного аудита было принято решение перенести владение инфраструктурным состоянием проверки согласованности потока сделок (**Trade Stream Consistency**) из общего Runtime Registry в специализированное хранилище состояний:
```text
TradeStreamStateStore
```
Тем самым Runtime окончательно перестал владеть состоянием предметной области.
После завершения данного этапа стало возможным провести повторный аудит уже всей подсистемы получения сделок в контексте полной архитектуры Dzentra.
Основной целью Build 060.21 является определение архитектурных контрактов взаимодействия между уже реализованными подсистемами без изменения их ответственности.
Именно этот Build завершает проектирование слоя Runtime и подготавливает основу для его прикладной реализации в последующих этапах.
---
# Предпосылки Build 060.21
К началу данного Build в проекте уже реализованы практически все фундаментальные компоненты подсистемы получения сделок.
Независимо друг от друга существуют:
```text
WebSocket Runtime
WebSocket Adapter
Trades Feed
Trade Stream Consistency
Trade Recovery
```
Каждая из перечисленных подсистем имеет собственную область ответственности, собственный публичный API и полностью покрыта модульными тестами.
При этом отсутствует единый слой интеграции между транспортной инфраструктурой и предметной областью получения рыночных данных.
Именно отсутствие такого слоя не позволяет перейти к реализации полноценного жизненного цикла получения Trade Stream.
---
# Цель Build 060.21
Build 060.21 не создаёт нового поведения системы.
Он не добавляет:
- новые алгоритмы;
- новые модели;
- новые механизмы обработки данных.
Его задача значительно более фундаментальна.
Build формализует публичные контракты взаимодействия между уже существующими подсистемами.
После завершения этапа каждая подсистема будет взаимодействовать исключительно через утверждённые Protocol.
Это позволит:
- полностью устранить риск циклических зависимостей;
- изолировать Runtime от бизнес-логики получения данных;
- обеспечить независимое тестирование компонентов;
- подготовить систему к дальнейшей реализации Runtime Service.
---
# Место Build 060.21 в общей дорожной карте
Развитие подсистемы Trades Feed выполняется последовательно.
```text
060.18
Trade Stream Consistency
```
```text
060.19
Trade Recovery
```
```text
060.20
Trade Runtime (первая архитектура)
```
```text
060.20.1
Перенос владельца состояния
```
```text
060.21
Runtime Integration Contracts
```
```text
060.22
Trade Runtime Service
```
```text
060.23
Acquisition Integration
```
```text
060.24
Reconnect & Runtime Recovery
```
```text
060.25
Integration & Regression
```
```text
060.26
Final Documentation
```
Каждый этап вводит только один новый архитектурный уровень.
Именно это позволяет сохранять стабильность системы на протяжении всей миграции.
---
# Архитектурный результат Build 060.20.1
После завершения предыдущего этапа архитектура приобрела следующий вид.
```text
Trade
TradeStreamConsistencyController
TradeStreamStateStore
TradeStreamState
```
При этом Runtime полностью перестал владеть инфраструктурным состоянием.
Это решение соответствует общей архитектуре Dzentra.
Каждый модуль отвечает исключительно за собственную область ответственности.
Никакие инфраструктурные компоненты не владеют состоянием предметной области.
---
# Что остаётся нерешённым
Несмотря на завершённую декомпозицию подсистем Consistency и Recovery, между Runtime и Trades Feed по-прежнему отсутствует архитектурный слой взаимодействия.
На сегодняшний день Runtime существует как полностью самостоятельная транспортная подсистема.
Trades Feed также существует как самостоятельная подсистема получения рыночных данных.
Однако отсутствует формализованный контракт, определяющий:
- каким образом Feed использует Runtime;
- каким образом Runtime предоставляет свои возможности;
- где проходит граница ответственности между транспортной инфраструктурой и бизнес-логикой получения сделок.
Именно устранение этой неопределённости является предметом Build 060.21.
---
# Основной архитектурный принцип
В ходе архитектурного аудита было принято ключевое решение, которое определяет всю дальнейшую разработку Runtime.
**Runtime остаётся полностью инфраструктурным слоем.**
Это означает:
Runtime предоставляет инфраструктурные возможности.
Runtime не управляет предметной областью.
Runtime ничего не знает о сделках.
Runtime ничего не знает о свечах.
Runtime ничего не знает о котировках.
Runtime ничего не знает о механизмах проверки последовательности сообщений.
Runtime ничего не знает о восстановлении пропусков.
Все знания о предметной области остаются внутри подсистем **Market Data Acquisition**.
Именно это решение становится фундаментом всех последующих Build.
---
# Почему Runtime не должен зависеть от Acquisition
На первый взгляд может показаться естественным сделать Runtime частью Trades Feed.
Однако подобное решение приводит к нарушению слоистой архитектуры.
Рассмотрим зависимости.
Правильное направление выглядит следующим образом:
```text
Trades Feed
Runtime Protocol
Runtime Implementation
```
То есть предметная область использует инфраструктуру.
Но никогда наоборот.
Если же Runtime начнёт зависеть от Feed, получится следующая схема:
```text
Runtime
Trades Feed
```
В этом случае инфраструктура начинает знать о прикладной области.
Позже Runtime неизбежно начнёт содержать:
- обработку Trade;
- обработку Quote;
- обработку Candles;
- обработку Recovery;
- обработку Consistency.
Фактически Runtime превратится во второй Acquisition Layer.
Подобное решение противоречит принципу Single Responsibility и разрушает возможность повторного использования Runtime другими потоками данных.
---
# Архитектурная роль Runtime
После завершения Build 060.21 Runtime окончательно получает следующую ответственность.
```text
Runtime отвечает исключительно за:
• жизненный цикл WebSocket;
• транспортные подключения;
• отправку команд;
• получение транспортных сообщений;
• переподключение;
• heartbeat;
• генерацию инфраструктурных событий.
```
Runtime не принимает решений относительно содержимого сообщений.
Runtime не знает, что именно передаётся через WebSocket.
Для него существует лишь поток транспортных данных.
---
# Архитектурная роль Trades Feed
В отличие от Runtime, Trades Feed отвечает исключительно за предметную область получения сделок.
Именно здесь сосредоточена логика:
- подписки на поток сделок;
- обработки транспортных сообщений;
- преобразования сообщений в каноническую модель;
- проверки последовательности;
- восстановления пропусков;
- передачи данных в следующие уровни системы.
Таким образом Runtime предоставляет инфраструктуру, а Feed определяет, каким образом эта инфраструктура используется.
---
# Новый слой интеграции
Для устранения прямых зависимостей вводится отдельный слой интеграционных контрактов.
После Build 060.21 взаимодействие будет выглядеть следующим образом.
```text
Runtime
Runtime Protocol Layer
Trades Runtime Adapter
Trades Feed
```
Feed зависит исключительно от публичных Protocol.
Runtime также реализует только Protocol.
Ни одна сторона не знает о внутреннем устройстве другой.
---
# Какие Protocol должны появиться
После архитектурного анализа становится очевидно, что существующих Protocol недостаточно.
В настоящий момент имеются лишь транспортные контракты.
```text
WebSocketTransportProtocol
WebSocketSessionProtocol
WebSocketSubscriptionManagerProtocol
```
Они описывают низкоуровневые механизмы работы WebSocket.
Но они ничего не говорят о жизненном цикле Runtime как сервиса.
Следовательно требуется следующий уровень абстракции.
---
# Runtime Service Protocol
Главным новым контрактом становится Runtime Service Protocol.
Именно он описывает полный жизненный цикл Runtime.
Примерный набор операций выглядит следующим образом.
```text
connect()
disconnect()
subscribe()
unsubscribe()
send()
is_connected()
connection_state()
```
Обращает на себя внимание важная особенность.
Все перечисленные методы относятся исключительно к транспортной инфраструктуре.
Ни один из них не содержит понятий:
- Trade;
- Quote;
- Candle;
- Recovery;
- Consistency.
Тем самым сохраняется полная независимость Runtime.
---
# Runtime Event Protocol
Следующим уровнем становятся инфраструктурные события.
На сегодняшний день существуют отдельные Event-модели.
Однако отсутствует единый контракт их использования.
После Build 060.21 Runtime публикует только инфраструктурные события.
Например:
```text
Connected
Disconnected
ReconnectStarted
ReconnectFinished
HeartbeatTimeout
TransportError
```
Получатель сам принимает решение, что делать с этими событиями.
Runtime ничего не знает о реакции системы.
---
# Runtime Command Protocol
Аналогичным образом формализуется слой команд.
Вместо непосредственного вызова внутренних механизмов Runtime вводится единый командный контракт.
Например:
```text
ConnectCommand
DisconnectCommand
SubscribeCommand
UnsubscribeCommand
ShutdownCommand
```
Все команды являются транспортными.
Они не содержат бизнес-логики.
---
# Runtime Message Flow
После завершения Build поток взаимодействия становится полностью линейным.
```text
Trades Feed
Runtime Service Protocol
Runtime
WebSocket
Exchange
```
Обратный поток строится аналогичным образом.
```text
Exchange
Runtime
Runtime Events
Trades Feed
Consistency
Recovery
```
Каждый уровень отвечает только за собственную часть обработки.
Никакие слои не пересекают границы ответственности.
---
# Build Scope
В рамках Build 060.21 производится исключительно интеграция Runtime Protocol Layer.
Изменения не затрагивают:
- Recovery;
- Consistency;
- Validation;
- Runtime Supervisor;
- Reconnect;
- Scheduler;
- Heartbeat.
Все перечисленные компоненты продолжают существовать в прежнем виде.
Изменяется исключительно способ их последующего подключения к Runtime.
---
# План реализации Build 060.21
Работы выполняются небольшими независимыми этапами.
## Этап 060.21.1
Аудит существующих Runtime Protocol.
Проверка:
- websocket_protocol.py;
- runtime_commands.py;
- runtime_events.py.
---
## Этап 060.21.2
Расширение Runtime Protocol Layer.
Добавляются отсутствующие инфраструктурные контракты.
---
## Этап 060.21.3
Создание Runtime Service Protocol.
Появляется единый контракт взаимодействия с Runtime.
---
## Этап 060.21.4
Интеграция существующих компонентов Runtime через новые Protocol.
Без изменения поведения.
---
## Этап 060.21.5
Полный прогон Runtime Unit Tests.
Подтверждение отсутствия регрессии.
---
# Ожидаемый результат
После завершения Build 060.21 архитектура Runtime приобретает окончательный вид.
```text
Acquisition Layer
Trades Feed / Quotes Feed / OHLC Feed
Runtime Service Protocol
┌────────────────────────────┐
│ Runtime Layer │
│ │
│ Commands │
│ Events │
│ Session │
│ Transport │
│ Subscription Manager │
└────────────────────────────┘
Exchange Transport
```
Все последующие Build будут использовать именно этот публичный слой.
Никаких дополнительных прямых зависимостей от Runtime больше вводиться не будет.
---
# Архитектурные гарантии после Build 060.21
После завершения данного этапа система получает следующие гарантии.
## 1. Инверсия зависимостей полностью соблюдается
Ни один инфраструктурный компонент не знает о предметной области.
Runtime не импортирует:
- Trades Feed;
- Quotes Feed;
- Candles Feed;
- Recovery;
- Consistency.
---
## 2. Runtime становится полностью переиспользуемым
Любой поток данных сможет использовать Runtime без модификации его кода.
Например:
```text
Trades Feed
Quotes Feed
OHLC Feed
Order Book Feed
Funding Feed
Index Feed
```
Все они будут работать через одинаковый Runtime Service Protocol.
---
## 3. Runtime становится тестируемым независимо
Все Runtime Unit Tests могут запускаться без:
- Feed;
- Acquisition;
- Exchange Adapter;
- Recovery.
Тестируется исключительно инфраструктурное поведение.
---
## 4. Feed становится независимым от реализации Runtime
Trades Feed знает только публичный контракт Runtime.
Следовательно Runtime можно заменить другой реализацией без изменения Feed.
Например:
```text
Current WebSocket Runtime
Future FIX Runtime
Future gRPC Runtime
Future Simulator Runtime
```
Feed останется неизменным.
---
## 5. Build 060.22 становится локальным
Следующий Build будет посвящён реализации Runtime Service.
Поскольку интерфейсы уже определены в Build 060.21, изменения затронут только внутреннюю реализацию Runtime.
Публичные контракты останутся неизменными.
Это существенно снижает риск регрессии.
---
# Итог
Build 060.21 завершает формирование архитектурного слоя Runtime Protocol Integration.
В результате:
- Runtime окончательно отделяется от предметной области Market Data Acquisition;
- взаимодействие осуществляется исключительно через публичные Protocol;
- все транспортные зависимости становятся инвертированными;
- Runtime превращается в независимый инфраструктурный сервис;
- создаётся стабильная контрактная база для последующих Build 060.22060.25 без необходимости дальнейшего изменения архитектуры Protocol Layer.
---
# Приложение A. Эволюция архитектуры Runtime
## До Build 060.21
```text
Trades Feed
WebSocketTransportProtocol
Runtime Components
Commands
Events
Session
Transport
```
Недостатки данной схемы:
- отсутствует единая точка входа в Runtime;
- Feed вынужден знать набор отдельных инфраструктурных компонентов;
- невозможно заменить Runtime целиком;
- отсутствует единый сервисный контракт.
---
## После Build 060.21
```text
Trades Feed
RuntimeServiceProtocol
┌────────────────┴────────────────┐
│ │
▼ ▼
Runtime Commands Runtime Events
│ │
└────────────────┬────────────────┘
Runtime Implementation
WebSocketTransportProtocol
WebSocket
Exchange
```
В новой архитектуре весь Runtime скрывается за единым публичным сервисным контрактом.
Trades Feed больше не зависит от внутренних компонентов Runtime.
---
# Приложение B. Dependency Graph
После Build 060.21 зависимости приобретают следующий вид.
```text
Trades Feed
RuntimeServiceProtocol
Runtime
├──────────────► Runtime Commands
├──────────────► Runtime Events
├──────────────► Session Protocol
├──────────────► Subscription Protocol
└──────────────► Transport Protocol
Exchange Adapter
```
Ни одна зависимость не направлена обратно к Feed.
---
# Приложение C. Build Boundary
В Build 060.21 разрешается изменять только следующие компоненты.
```text
runtime/
websocket_protocol.py
runtime_commands.py
runtime_events.py
```
При необходимости допускается добавление новых файлов Protocol Layer.
Не допускается изменение:
```text
consistency/
recovery/
validation/
processing/
analytics/
storage/
```
Также не изменяются:
```text
Trades Feed
Recovery Controller
Consistency Controller
Exchange Adapter
```
Их интеграция будет выполняться на следующих этапах Roadmap.
---
# Приложение D. Следующие этапы
После завершения Build 060.21 дальнейшая последовательность работ выглядит следующим образом.
```text
060.22
Runtime Service Integration
060.23
Acquisition Integration
060.24
Reconnect & Runtime Recovery
060.25
Integration & Regression
060.26
Final Documentation
```
Таким образом Build 060.21 завершает исключительно проектирование и интеграцию контрактов Runtime Protocol Layer, создавая стабильную основу для последующей реализации Runtime Service без нарушения уже сформированной архитектуры подсистемы Market Data Acquisition.