32 KiB
Build 060.15 — Unified WebSocket Routing
Engineering Migration Report
Контроль документа
| Свойство | Значение |
|---|---|
| Build | 060.15 |
| Название | Unified WebSocket Routing |
| Статус | Completed |
| Проект | Dzentra |
| Подсистема | Market Data Acquisition |
| Компонент | Trades Feed |
| Версия | 1.0 |
Цель Build
После завершения Build 060.14 система получила полностью реализованный уровень WebSocket Trade Adapter.
К этому моменту Pipeline обработки WebSocket Trade уже гарантировал:
- корректность структуры транспортного документа;
- успешное построение транспортной модели;
- корректность всех обязательных значений;
- успешное преобразование транспортной модели в каноническую модель предметной области;
- наличие единой точки входа транспортного Pipeline.
Однако полученный Adapter ещё не был встроен в существующую инфраструктуру получения WebSocket-сообщений.
Архитектура Dzentra уже содержала единый компонент маршрутизации входящих сообщений —
DzengiUnifiedWebSocketAdapter
который определял тип входящего сообщения и направлял его в соответствующий специализированный Adapter.
До начала Build поддерживались только два типа сообщений:
Quote
и
OHLC
Поддержка сообщений
Trade
отсутствовала.
В результате Trade Pipeline существовал как полностью реализованный, но оставался недоступным для общего механизма маршрутизации WebSocket.
Основная задача Build заключается в расширении существующего Unified WebSocket Routing без изменения ранее реализованной архитектуры.
После завершения Build компонент
DzengiUnifiedWebSocketAdapter
должен уметь автоматически определять сообщения
internal.trade
и передавать их в специализированный Adapter обработки Trade.
При этом Build не затрагивает:
- WebSocket Runtime;
- транспортный протокол;
- Schema Validation;
- Parser;
- Value Validation;
- Mapper;
- внутреннюю архитектуру Trade Adapter;
- Trades Feed.
Предпосылки
К началу Build архитектура WebSocket уже содержала единый механизм маршрутизации сообщений.
Он обеспечивал разделение различных типов транспортных событий между специализированными Adapter.
Конвейер обработки выглядел следующим образом.
Raw WebSocket Message
│
▼
DzengiUnifiedWebSocketAdapter
│
├────────► Quote Adapter
│
└────────► OHLC Adapter
Каждый специализированный Adapter полностью инкапсулировал собственный транспортный Pipeline.
После завершения Build 060.14 аналогичный Pipeline уже существовал и для Trade.
ValidatedWebSocketTradeDocument
│
▼
WebSocket Trade Adapter
│
├────────► Parser
│
├────────► Value Validation
│
├────────► Mapper
│
▼
Trade
Однако данный Adapter не был подключён к общему механизму маршрутизации.
В результате система не могла автоматически обрабатывать входящие сообщения о сделках, несмотря на полностью реализованный транспортный Pipeline.
Таким образом архитектура Unified WebSocket Routing оставалась незавершённой.
Архитектурное основание
Одним из фундаментальных принципов архитектуры Dzentra является централизованная маршрутизация транспортных сообщений.
Определение типа входящего сообщения должно происходить исключительно в одном месте системы.
Именно эту задачу выполняет
DzengiUnifiedWebSocketAdapter
После определения типа события дальнейшая обработка полностью передаётся специализированному Adapter соответствующего типа данных.
Полная схема обработки WebSocket-сообщений принимает следующий вид.
Raw WebSocket Message
│
▼
Unified Routing
│
├────────► Quote Adapter
│
├────────► OHLC Adapter
│
└────────► Trade Adapter
Каждый специализированный Adapter полностью инкапсулирует собственный транспортный Pipeline.
Unified Router принципиально не выполняет:
- Schema Validation;
- Parser;
- Value Validation;
- Mapper;
- бизнес-логику;
- принятие торговых решений;
- обработку Runtime.
Его единственная ответственность — определить тип входящего сообщения и передать его соответствующему Adapter.
Подобное разделение ответственности обеспечивает:
- единое место маршрутизации всех WebSocket-событий;
- независимое развитие отдельных Pipeline;
- повторное использование существующих Adapter;
- отсутствие дублирования логики определения типа сообщений.
Результаты архитектурного аудита
Перед реализацией Build был выполнен аудит существующей архитектуры WebSocket Routing.
В ходе анализа подтверждено наличие полностью реализованного компонента
DzengiUnifiedWebSocketAdapter
который уже обеспечивал маршрутизацию сообщений Quote и OHLC.
Также был выполнен аудит транспортного уровня Runtime.
Анализ подтвердил, что
runtime/websocket_protocol.py
не содержит логики определения типов сообщений и не должен выполнять:
- Schema Validation;
- Parser;
- Value Validation;
- Mapper;
- транспортную маршрутизацию.
Данный принцип уже закреплён архитектурой подсистемы Market Data Acquisition.
Кроме того, аудит подтвердил полную готовность WebSocket Trade Adapter, реализованного в Build 060.14.
Таким образом единственным отсутствующим элементом архитектуры являлось подключение нового Adapter к существующему механизму Unified Routing.
Архитектурное решение
По результатам проведённого аудита было принято решение сохранить существующую архитектуру маршрутизации без изменения её принципов.
В компонент
DzengiUnifiedWebSocketAdapter
добавлена поддержка нового специализированного Adapter.
После определения значения
destination = "internal.trade"
маршрутизатор передаёт документ в
DzengiWebSocketTradeAdapter
который выполняет полный транспортный Pipeline обработки и возвращает готовую каноническую модель
Trade
После завершения обработки вызывающая сторона получает результат в виде одной из трёх канонических моделей предметной области.
Quote
CandleCloseEvent
Trade
Конвейер обработки WebSocket принимает следующий вид.
Raw WebSocket Message
│
▼
DzengiUnifiedWebSocketAdapter
│
├────────► Quote Adapter
│ │
│ ▼
│ Quote
│
├────────► OHLC Adapter
│ │
│ ▼
│ CandleCloseEvent
│
└────────► Trade Adapter
│
▼
Trade
Build 060.15 не изменяет архитектуру Runtime, не затрагивает ранее реализованные Pipeline и не изменяет внутреннюю структуру специализированных Adapter.
Он исключительно расширяет существующий механизм Unified Routing новым типом сообщений.
Реализованный уровень Unified Routing
В файл
src/market_data/acquisition/adapters/dzengi/websocket.py
добавлен специализированный Adapter
DzengiWebSocketTradeAdapter
Новый Adapter становится частью существующей архитектуры маршрутизации WebSocket-сообщений и отвечает исключительно за подключение уже реализованного транспортного Pipeline Trade к Unified Router.
Во время обработки сообщения Adapter последовательно выполняет:
- Schema Validation;
- WebSocket Trade Adapter.
При этом полный транспортный Pipeline продолжает оставаться инкапсулированным внутри ранее реализованного Adapter Build 060.14.
После успешного завершения обработки вызывающая сторона получает готовую каноническую модель
Trade
Промежуточные транспортные модели по-прежнему не покидают слой адаптеров.
Почему маршрутизация выполняется в Unified Adapter
Во время проектирования отдельно рассматривался вопрос о переносе логики определения типа сообщения в Runtime.
По результатам анализа данный вариант был отклонён.
Основные причины:
- Runtime не должен знать типы рыночных сообщений;
- Runtime не должен зависеть от конкретной биржи;
- Runtime не должен содержать транспортную маршрутизацию;
- вся логика определения типа сообщения уже сосредоточена в Unified Adapter.
Таким образом архитектурная ответственность остаётся неизменной.
Runtime отвечает исключительно за получение транспортных сообщений.
Unified Adapter отвечает исключительно за определение их типа.
Специализированные Adapter отвечают исключительно за преобразование данных.
Подобное разделение полностью соответствует базовым архитектурным принципам Dzentra.
Последовательность обработки
После завершения Build полный конвейер обработки WebSocket-сообщений принимает следующий вид.
Raw WebSocket Message
│
▼
DzengiUnifiedWebSocketAdapter
│
├────────► Quote Adapter
│ │
│ ▼
│ Quote
│
├────────► OHLC Adapter
│ │
│ ▼
│ CandleCloseEvent
│
└────────► Trade Adapter
│
▼
Schema Validation
│
▼
WebSocket Trade Adapter
│
├────────► Parser
├────────► Value Validation
├────────► Mapper
│
▼
Trade
Каждый уровень Pipeline сохраняет собственную область ответственности.
Ни один из существующих компонентов не изменяет своё назначение.
Использование существующих компонентов
Build 060.15 не вводит новых механизмов обработки транспортных данных.
Unified Router повторно использует уже существующую инфраструктуру проекта.
Для обработки Quote используются:
DzengiWebSocketQuoteAdapter
Для обработки OHLC используются:
DzengiWebSocketOhlcAdapter
Для обработки Trade используются:
DzengiWebSocketTradeAdapter
Новый специализированный Adapter, в свою очередь, повторно использует ранее реализованный
adapt_websocket_trade_document(...)
из Build 060.14.
Таким образом Build не дублирует существующую функциональность и полностью основан на уже реализованных компонентах проекта.
Проброс исключений
Unified Router не выполняет собственной обработки ошибок.
Все исключения специализированных Adapter пробрасываются вызывающей стороне без изменения.
При обработке Quote сохраняется существующий механизм обработки ошибок.
При обработке OHLC сохраняется существующий механизм обработки ошибок.
При обработке Trade сохраняются исключения:
TradeSchemaError
TradeParseError
TradeValueError
TradeMappingError
Подобный подход сохраняет единообразную архитектуру обработки ошибок во всей подсистеме Market Data Acquisition.
Изменённые файлы
В рамках Build были изменены только два файла.
Unified Adapter
src/market_data/acquisition/adapters/dzengi/websocket.py
Добавлен специализированный
DzengiWebSocketTradeAdapter
и расширена маршрутизация сообщений.
Существующая логика обработки Quote и OHLC не изменялась.
Unit-тесты
tests/unit/market_data/acquisition/adapters/dzengi/test_websocket_unified_adapter.py
Добавлен unit-тест маршрутизации сообщений
internal.trade
Все существующие тесты сохранены без изменений.
Добавленные тесты
В рамках Build реализован дополнительный unit-тест, подтверждающий корректную маршрутизацию сообщений
internal.trade
через Unified Router.
Проверка успешной маршрутизации Trade
Подтверждается, что сообщение
destination = "internal.trade"
автоматически направляется в специализированный
DzengiWebSocketTradeAdapter
и после завершения полного транспортного Pipeline возвращается каноническая модель
Trade
Результаты тестирования
После завершения реализации выполнен запуск целевого набора unit-тестов нового Adapter.
PYTHONPATH="$PWD" python -m pytest \
tests/unit/market_data/acquisition/adapters/dzengi/test_websocket_trade_adapter.py -v
Результат:
4 passed
После этого выполнено тестирование Unified Router.
PYTHONPATH="$PWD" python -m pytest \
tests/unit/market_data/acquisition/adapters/dzengi/test_websocket_unified_adapter.py -v
Результат:
10 passed
Подтверждена корректная маршрутизация:
- Quote;
- OHLC;
- Trade.
Также подтверждено отсутствие изменений существующей функциональности.
Регрессионное тестирование Adapter
После завершения реализации выполнен полный запуск тестов адаптеров Dzengi.
PYTHONPATH="$PWD" python -m pytest \
tests/unit/market_data/acquisition/adapters/dzengi
Результат:
302 passed
Регрессий существующих Adapter, Parser, Mapper и Validation не обнаружено.
Регрессионное тестирование Market Data
После завершения реализации выполнен запуск полного набора unit-тестов подсистемы Market Data.
PYTHONPATH="$PWD" python -m pytest \
tests/unit/market_data
Результат:
914 passed
Подтверждено отсутствие регрессий во всех ранее реализованных компонентах подсистемы.
Полное регрессионное тестирование
После завершения реализации выполнен полный запуск unit-тестов проекта.
PYTHONPATH="$PWD" python -m pytest
Результат:
1235 passed
Регрессий существующей функциональности не обнаружено.
Добавление поддержки Trade в Unified Routing не повлияло на существующие механизмы обработки Quote, OHLC, REST Trade и остальные подсистемы проекта.
Проверка компиляции
После завершения реализации выполнена полная проверка компиляции проекта.
python -m compileall src tests
Компиляция завершилась успешно.
Ошибок синтаксиса не обнаружено.
Все изменённые файлы успешно компилируются и не нарушают целостность проекта.
Проверка Git diff
После завершения реализации выполнена финальная проверка изменений.
git diff --check
Результат:
без замечаний
Проверка подтвердила отсутствие:
- trailing whitespace;
- ошибок окончания строк;
- конфликтов diff;
- нарушений форматирования.
Scope Build 060.15
В рамках данного Build реализован исключительно уровень
Unified WebSocket Routing
Build не включает:
- WebSocket Runtime;
- WebSocket Protocol;
- Trades Feed;
- Dispatcher;
- Event Bus;
- Runtime Integration;
- обработку торговых решений.
Подобное ограничение полностью соответствует принятому принципу атомарной реализации Build.
Каждый этап дорожной карты реализует только один архитектурный уровень системы.
Архитектурный результат
После завершения Build система содержит полностью реализованный механизм Unified WebSocket Routing.
Конвейер обработки принимает следующий вид.
Raw WebSocket Message
│
▼
DzengiUnifiedWebSocketAdapter
│
├────────► Quote Adapter
│ │
│ ▼
│ Quote
│
├────────► OHLC Adapter
│ │
│ ▼
│ CandleCloseEvent
│
└────────► Trade Adapter
│
▼
Trade
Unified Router полностью изолирует вызывающий код от деталей транспортного Pipeline.
Все специализированные Adapter продолжают самостоятельно выполнять полный цикл преобразования транспортных данных в канонические модели предметной области.
Состояние WebSocket Trade Pipeline
После завершения Build 060.15 транспортный конвейер принимает следующий вид.
Raw WebSocket Trade
│
▼
Unified WebSocket Routing
│
▼
Schema Validation
│
▼
ValidatedWebSocketTradeDocument
│
▼
Adapter
│
├────────► Parser
│
├────────► Value Validation
│
├────────► Mapper
│
▼
Trade
Статус реализации компонентов:
| Компонент | Build | Статус |
|---|---|---|
| Canonical Trade Model | 060.1 | ✔ Completed |
| WebSocket Trade Transport Model | 060.9 | ✔ Completed |
| WebSocket Trade Schema Validation | 060.10 | ✔ Completed |
| WebSocket Trade Parser | 060.11 | ✔ Completed |
| WebSocket Trade Value Validation | 060.12 | ✔ Completed |
| WebSocket Trade Mapper | 060.13 | ✔ Completed |
| WebSocket Trade Adapter | 060.14 | ✔ Completed |
| Unified WebSocket Routing | 060.15 | ✔ Completed |
| Trades Feed | 060.16 | Pending |
Соблюдение архитектурных принципов
В рамках Build полностью сохранены архитектурные инварианты Dzentra.
Локальность изменений
Изменены только:
src/market_data/acquisition/adapters/dzengi/websocket.py;tests/unit/market_data/acquisition/adapters/dzengi/test_websocket_unified_adapter.py.
Все остальные компоненты проекта остались без изменений.
Повторное использование архитектуры
Build полностью использует существующую архитектуру Unified Router.
Новый механизм маршрутизации не проектировался.
Расширен уже существующий механизм обработки сообщений.
Повторное использование инфраструктуры
Build полностью использует ранее реализованные компоненты проекта:
- Quote Adapter;
- OHLC Adapter;
- WebSocket Trade Adapter.
Новые Parser, Mapper или Validation не создавались.
Вся существующая инфраструктура используется повторно.
Разделение ответственности
Unified Router отвечает исключительно за определение типа входящего сообщения.
Специализированные Adapter отвечают исключительно за преобразование транспортных данных.
Runtime продолжает отвечать исключительно за получение транспортных сообщений.
Подобное разделение полностью соответствует архитектурным принципам Dzentra.
Обратная совместимость
Существующая обработка:
- Quote;
- OHLC;
- REST Trade;
не изменилась.
Добавленная поддержка Trade полностью совместима с существующей архитектурой и не оказывает влияния на ранее реализованные компоненты проекта.
Архитектурные решения Build (ADR)
ADR-060.15-001
Определение типа WebSocket-сообщения выполняется исключительно Unified Router.
Runtime не должен содержать транспортную маршрутизацию.
ADR-060.15-002
Каждый тип рыночных данных обрабатывается собственным специализированным Adapter.
Unified Router не выполняет преобразование транспортных данных.
Он только определяет тип сообщения и передаёт его соответствующему Adapter.
ADR-060.15-003
Trade Pipeline повторно использует ранее реализованный Adapter Build 060.14.
Unified Router не вызывает Parser, Value Validation и Mapper напрямую.
Полный транспортный Pipeline остаётся полностью инкапсулированным внутри специализированного Adapter.
ADR-060.15-004
Подключение нового типа сообщений не изменяет существующую архитектуру Runtime.
Поддержка Trade реализуется исключительно расширением Unified Router.
Это сохраняет независимость Runtime от особенностей конкретных транспортных сообщений.
Критерии завершения Build
Build 060.15 считается завершённым, поскольку выполнены все поставленные задачи.
- ✔ реализован
DzengiWebSocketTradeAdapter; - ✔ Trade подключён к Unified Router;
- ✔ добавлена маршрутизация сообщений
internal.trade; - ✔ Runtime не изменён;
- ✔ транспортный Pipeline Trade повторно использован без дублирования;
- ✔ сохранено разделение ответственности между Runtime, Router и Adapter;
- ✔ добавлен unit-тест маршрутизации Trade;
- ✔ успешно пройдены целевые тесты;
- ✔ успешно пройдена регрессия Adapter;
- ✔ успешно пройдена регрессия Market Data;
- ✔ успешно пройдена полная регрессия проекта (
1235 passed); - ✔ проект успешно компилируется;
- ✔
git diff --checkне выявил замечаний; - ✔ изменения полностью укладываются в согласованный scope Build.
Следующий этап
Следующим этапом дорожной карты является
Build 060.16 — Trades Feed
Цель следующего Build:
- реализовать специализированный Feed обработки сделок;
- подключить поток Trade к инфраструктуре Market Data Acquisition;
- обеспечить публикацию канонических моделей
Trade; - подготовить основу для дальнейшего использования сделок подсистемами анализа рынка и торговых стратегий.
Итог
Build 060.15 завершил интеграцию WebSocket Trade Pipeline в существующий механизм Unified WebSocket Routing.
Новая реализация полностью повторно использует архитектуру Dzentra, не изменяет Runtime, не дублирует транспортный Pipeline и сохраняет строгое разделение ответственности между компонентами системы.
После завершения Build все три типа рыночных данных — Quote, CandleCloseEvent и Trade — обрабатываются единым механизмом маршрутизации и возвращаются в виде канонических моделей предметной области.
Build ограничен согласованным scope, успешно прошёл целевое и полное регрессионное тестирование, подтвердил отсутствие регрессий и завершил интеграцию WebSocket Trade в общий механизм маршрутизации Market Data Acquisition.