Files
dzentra_bot/docs/migrations/build_060_15.md

32 KiB
Raw Permalink Blame History

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 последовательно выполняет:

  1. Schema Validation;
  2. 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.