Files
dzentra_bot/docs/migrations/build_059_10.md

11 KiB
Raw Permalink Blame History

Build 059.10 — Runtime Transport Message Models

Migration Build


Цель Build

После завершения Build 059.9 в проекте появился самостоятельный Runtime слой, содержащий транспортные контракты:

  • WebSocketTransportProtocol
  • WebSocketSessionProtocol
  • WebSocketSubscriptionManagerProtocol

Следующим логическим шагом является создание моделей данных, которыми будут обмениваться компоненты Runtime.

Данный Build вводит первый уровень моделей Runtime — Transport Message Models.


Причина появления Transport Message Models

До настоящего момента Runtime содержал только интерфейсы взаимодействия.

Например:

Transport
      │
connect()
disconnect()
send()
receive()

Однако отсутствовало описание того, какие именно объекты транспорт должен принимать и возвращать.

Использование непосредственно типов

str
bytes

делает код менее выразительным.

Невозможно определить:

  • транспортное сообщение это;
  • сериализованный JSON;
  • бинарный protobuf;
  • внутренний объект Runtime.

Поэтому вводится отдельный уровень моделей транспортных сообщений.


Архитектурная идея

Главная задача данного Build — отделить транспортные данные от всех остальных сущностей системы.

Получается следующая иерархия.

Transport
        │
Transport Message
        │
Parser
        │
Validation
        │
Mapper
        │
Canonical Models

Transport знает только одно:

существует некоторый payload.

Он совершенно не знает:

  • что находится внутри payload;
  • как этот payload будет интерпретирован;
  • является ли он JSON;
  • относится ли он к конкретной бирже;
  • какие модели будут построены дальше.

Это полностью соответствует принципу Single Responsibility.


Почему Runtime не знает про WebSocket

Несмотря на то, что текущим транспортом является WebSocket, Runtime проектируется максимально универсальным.

Поэтому модели транспортных сообщений намеренно не содержат слов:

  • WebSocket
  • Dzengi
  • Exchange
  • Candle
  • Quote

Runtime оперирует исключительно транспортными сообщениями.

Это позволяет в будущем использовать один и тот же Runtime для различных транспортов:

  • WebSocket;
  • HTTP Streaming;
  • FIX;
  • gRPC Streaming;
  • внутренние очереди сообщений.

Новые модели

Создан новый файл

src/market_data/acquisition/runtime/transport_messages.py

В Build добавлены две immutable модели.


TransportTextMessage

Представляет текстовое транспортное сообщение.

Содержит единственное поле:

payload: str

Никакой дополнительной информации модель не содержит.

Она не знает:

  • что внутри находится JSON;
  • является ли сообщение командой;
  • является ли сообщение событием;
  • содержит ли сообщение свечу.

Она является исключительно контейнером транспортного текста.


TransportBinaryMessage

Представляет бинарное транспортное сообщение.

Содержит единственное поле

payload: bytes

Как и текстовая модель, не содержит никакой информации о содержимом.

Runtime рассматривает бинарные данные как непрозрачный набор байтов.


Почему модели содержат только payload

Во время проектирования рассматривались варианты добавить дополнительные поля.

Например:

message_type
encoding
channel
metadata
timestamp

От данной идеи было принято решение отказаться.

Причины следующие.

Причина №1

Транспорт не должен ничего знать о содержимом сообщения.

Если транспорт начинает анализировать содержимое сообщения, происходит смешение ответственности между Runtime и Parser.


Причина №2

Любые дополнительные поля являются предположениями относительно будущего транспорта.

На данном этапе архитектуры неизвестно:

  • понадобится ли message_type;
  • понадобится ли encoding;
  • понадобится ли channel;
  • понадобится ли metadata.

Следовательно, преждевременно добавлять подобные поля.


Причина №3

Минимальные immutable модели проще поддерживать.

При необходимости они могут быть расширены отдельным Build без нарушения обратной совместимости.


Почему здесь отсутствуют ConnectRequest

Во время проектирования рассматривалась идея добавить модели:

ConnectRequest
DisconnectRequest
SubscribeRequest
UnsubscribeRequest

Однако было принято решение отказаться от неё.

Причина заключается в разделении уровней ответственности.

ConnectRequest не является транспортным сообщением.

Это команда Runtime.


Почему отсутствуют Ping/Pong

По аналогичной причине.

Ping и Pong являются частью логики Runtime.

Транспорт получает некоторый payload.

Что именно находится внутри этого payload, транспорт не анализирует.

Следовательно:

Ping/Pong должны появиться позднее вместе с Runtime Commands.


Новая архитектура Runtime

После завершения Build Runtime начинает разделяться на несколько независимых уровней.

Runtime

Transport Protocol
        │
Transport Messages
        │
Runtime Commands
        │
Runtime Events
        │
Runtime Services

Подобное разделение является значительно более устойчивым, чем смешение всех сущностей в одном модуле.


Обновлённый план Runtime

После выполнения Build 059.10 дальнейшее развитие Runtime выглядит следующим образом.

Build 059.11

Runtime Commands

Будут введены команды:

  • ConnectCommand
  • DisconnectCommand
  • SubscribeCommand
  • UnsubscribeCommand
  • SendTextCommand
  • SendBinaryCommand

Build 059.12

Runtime Events

Появятся события Runtime:

  • ConnectedEvent
  • DisconnectedEvent
  • SubscriptionRestoredEvent
  • HeartbeatTimeoutEvent
  • ReconnectStartedEvent
  • ReconnectCompletedEvent

Build 059.13

Subscription Manager

Полноценное управление активными подписками Runtime.


Build 059.14

WebSocket Session

Жизненный цикл Runtime Session.


Build 059.15

Transport Reliability

Инфраструктура Runtime:

  • Heartbeat
  • Reconnect
  • Ping/Pong
  • Scheduler
  • Recovery

Build 059.16

Runtime Integration

Интеграция нового Runtime с существующей цепочкой Acquisition.


Build 059.17

Runtime Validation & Documentation

Полная регрессия новой архитектуры и финальная документация.


Проверка Build

Выполнены проверки.

Компиляция

python -m compileall

Успешно.


Unit Tests

test_transport_messages.py

Все тесты успешно пройдены.

Проверяется:

  • создание моделей;
  • корректность хранения payload;
  • immutable поведение dataclass.

Runtime Regression

Проверена совместимость новой модели сообщений с ранее созданными Runtime Protocol.

Все проверки успешно завершены.


Проверка репозитория

Выполнен

git diff --check

Ошибок форматирования не обнаружено.


Итог

Build 059.10 завершает создание базового транспортного уровня Runtime.

После него Runtime уже содержит:

  • транспортные контракты;
  • транспортные модели сообщений.

Следующие Build будут постепенно добавлять поведение системы (Commands, Events, Session, Subscription Manager, Reconnect), не изменяя уже построенный фундамент.

Таким образом продолжается основной принцип миграции Dzentra:

  • каждый Build решает одну архитектурную задачу;
  • изменения являются минимальными и независимыми;
  • существующая цепочка Acquisition остаётся неизменной;
  • работающий торговый бот продолжает функционировать без необходимости одновременной полной миграции.