Build 060.21: integrate acquisition runtime protocols
This commit is contained in:
@@ -4,6 +4,48 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Protocol, runtime_checkable
|
from typing import Protocol, runtime_checkable
|
||||||
|
|
||||||
|
from src.market_data.acquisition.runtime.runtime_commands import (
|
||||||
|
ConnectCommand,
|
||||||
|
DisconnectCommand,
|
||||||
|
SendBinaryCommand,
|
||||||
|
SendTextCommand,
|
||||||
|
SubscribeCommand,
|
||||||
|
UnsubscribeCommand,
|
||||||
|
)
|
||||||
|
from src.market_data.acquisition.runtime.runtime_events import (
|
||||||
|
ConnectedEvent,
|
||||||
|
ConnectFailedEvent,
|
||||||
|
DisconnectedEvent,
|
||||||
|
HeartbeatTimeoutEvent,
|
||||||
|
MessageReceivedEvent,
|
||||||
|
MessageSentEvent,
|
||||||
|
ReconnectCompletedEvent,
|
||||||
|
ReconnectFailedEvent,
|
||||||
|
ReconnectStartedEvent,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
AcquisitionRuntimeCommand = (
|
||||||
|
ConnectCommand
|
||||||
|
| DisconnectCommand
|
||||||
|
| SubscribeCommand
|
||||||
|
| UnsubscribeCommand
|
||||||
|
| SendTextCommand
|
||||||
|
| SendBinaryCommand
|
||||||
|
)
|
||||||
|
|
||||||
|
AcquisitionRuntimeEvent = (
|
||||||
|
ConnectedEvent
|
||||||
|
| DisconnectedEvent
|
||||||
|
| ConnectFailedEvent
|
||||||
|
| MessageReceivedEvent
|
||||||
|
| MessageSentEvent
|
||||||
|
| ReconnectStartedEvent
|
||||||
|
| ReconnectCompletedEvent
|
||||||
|
| ReconnectFailedEvent
|
||||||
|
| HeartbeatTimeoutEvent
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@runtime_checkable
|
@runtime_checkable
|
||||||
class WebSocketTransportProtocol(Protocol):
|
class WebSocketTransportProtocol(Protocol):
|
||||||
@@ -76,4 +118,48 @@ class WebSocketSubscriptionManagerProtocol(Protocol):
|
|||||||
|
|
||||||
async def clear_subscriptions(self) -> None:
|
async def clear_subscriptions(self) -> None:
|
||||||
"""Очистить runtime-состояние активных подписок."""
|
"""Очистить runtime-состояние активных подписок."""
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@runtime_checkable
|
||||||
|
class AcquisitionRuntimeCommandDispatcherProtocol(Protocol):
|
||||||
|
"""
|
||||||
|
Контракт передачи инфраструктурных команд в Runtime.
|
||||||
|
|
||||||
|
Dispatcher принимает только типизированные Runtime-команды
|
||||||
|
и не содержит знаний о Trade, Feed, Consistency или Recovery.
|
||||||
|
|
||||||
|
Конкретная маршрутизация и выполнение команд будут реализованы
|
||||||
|
в последующих Build.
|
||||||
|
"""
|
||||||
|
|
||||||
|
async def dispatch(
|
||||||
|
self,
|
||||||
|
command: AcquisitionRuntimeCommand,
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Передать одну инфраструктурную команду в Runtime.
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@runtime_checkable
|
||||||
|
class AcquisitionRuntimeEventPublisherProtocol(Protocol):
|
||||||
|
"""
|
||||||
|
Контракт публикации инфраструктурных событий Runtime.
|
||||||
|
|
||||||
|
Publisher передаёт уже произошедшие инфраструктурные факты
|
||||||
|
заинтересованным потребителям и не определяет их реакцию.
|
||||||
|
|
||||||
|
Конкретный механизм доставки событий будет реализован
|
||||||
|
в последующих Build.
|
||||||
|
"""
|
||||||
|
|
||||||
|
async def publish(
|
||||||
|
self,
|
||||||
|
event: AcquisitionRuntimeEvent,
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Опубликовать одно инфраструктурное событие Runtime.
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from src.market_data.acquisition.runtime.websocket_protocol import (
|
from src.market_data.acquisition.runtime.websocket_protocol import (
|
||||||
|
AcquisitionRuntimeCommand,
|
||||||
|
AcquisitionRuntimeCommandDispatcherProtocol,
|
||||||
|
AcquisitionRuntimeEvent,
|
||||||
|
AcquisitionRuntimeEventPublisherProtocol,
|
||||||
WebSocketSessionProtocol,
|
WebSocketSessionProtocol,
|
||||||
WebSocketSubscriptionManagerProtocol,
|
WebSocketSubscriptionManagerProtocol,
|
||||||
WebSocketTransportProtocol,
|
WebSocketTransportProtocol,
|
||||||
@@ -43,6 +47,22 @@ class FakeWebSocketSubscriptionManager:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class FakeRuntimeCommandDispatcher:
|
||||||
|
async def dispatch(
|
||||||
|
self,
|
||||||
|
command: AcquisitionRuntimeCommand,
|
||||||
|
) -> None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class FakeRuntimeEventPublisher:
|
||||||
|
async def publish(
|
||||||
|
self,
|
||||||
|
event: AcquisitionRuntimeEvent,
|
||||||
|
) -> None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def test_transport_implementation_satisfies_protocol() -> None:
|
def test_transport_implementation_satisfies_protocol() -> None:
|
||||||
assert isinstance(FakeWebSocketTransport(), WebSocketTransportProtocol)
|
assert isinstance(FakeWebSocketTransport(), WebSocketTransportProtocol)
|
||||||
|
|
||||||
@@ -58,9 +78,43 @@ def test_subscription_manager_implementation_satisfies_protocol() -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_command_dispatcher_implementation_satisfies_protocol() -> None:
|
||||||
|
assert isinstance(
|
||||||
|
FakeRuntimeCommandDispatcher(),
|
||||||
|
AcquisitionRuntimeCommandDispatcherProtocol,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_event_publisher_implementation_satisfies_protocol() -> None:
|
||||||
|
assert isinstance(
|
||||||
|
FakeRuntimeEventPublisher(),
|
||||||
|
AcquisitionRuntimeEventPublisherProtocol,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_incomplete_transport_does_not_satisfy_protocol() -> None:
|
def test_incomplete_transport_does_not_satisfy_protocol() -> None:
|
||||||
class IncompleteTransport:
|
class IncompleteTransport:
|
||||||
async def connect(self) -> None:
|
async def connect(self) -> None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
assert not isinstance(IncompleteTransport(), WebSocketTransportProtocol)
|
assert not isinstance(IncompleteTransport(), WebSocketTransportProtocol)
|
||||||
|
|
||||||
|
|
||||||
|
def test_incomplete_command_dispatcher_does_not_satisfy_protocol() -> None:
|
||||||
|
class IncompleteCommandDispatcher:
|
||||||
|
pass
|
||||||
|
|
||||||
|
assert not isinstance(
|
||||||
|
IncompleteCommandDispatcher(),
|
||||||
|
AcquisitionRuntimeCommandDispatcherProtocol,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_incomplete_event_publisher_does_not_satisfy_protocol() -> None:
|
||||||
|
class IncompleteEventPublisher:
|
||||||
|
pass
|
||||||
|
|
||||||
|
assert not isinstance(
|
||||||
|
IncompleteEventPublisher(),
|
||||||
|
AcquisitionRuntimeEventPublisherProtocol,
|
||||||
|
)
|
||||||
|
|||||||
841
docs/migrations/build_060_21.md
Normal file
841
docs/migrations/build_060_21.md
Normal file
@@ -0,0 +1,841 @@
|
|||||||
|
# Build 060.21 — Runtime Protocol Integration
|
||||||
|
|
||||||
|
**Engineering Migration Report**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Контроль документа
|
||||||
|
|
||||||
|
| Свойство | Значение |
|
||||||
|
|----------|----------|
|
||||||
|
| Build | 060.21 |
|
||||||
|
| Название | Runtime Protocol Integration |
|
||||||
|
| Статус | Completed |
|
||||||
|
| Проект | Dzentra |
|
||||||
|
| Подсистема | Market Data Acquisition |
|
||||||
|
| Компонент | Acquisition Runtime Protocol Layer |
|
||||||
|
| Версия | 1.0 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Связанные документы
|
||||||
|
|
||||||
|
- `build_060_21_architecture.md` — архитектурная спецификация Build.
|
||||||
|
- `build_060_20_1.md` — Engineering Migration Report предыдущего корректирующего Build.
|
||||||
|
- `build_060_20_1_architecture.md` — спецификация переноса владельца состояния Trade Stream.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Цель Build
|
||||||
|
|
||||||
|
Build 060.20.1 завершил архитектурную корректировку подсистемы **Trades Feed (Time & Sales)** и окончательно закрепил владельца состояния проверки согласованности потока сделок.
|
||||||
|
|
||||||
|
После предыдущего этапа архитектура сопровождения состояния приняла следующий вид.
|
||||||
|
|
||||||
|
```text
|
||||||
|
TradeStreamConsistencyController
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
TradeStreamStateStore
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
TradeStreamState
|
||||||
|
```
|
||||||
|
|
||||||
|
Runtime перестал владеть состоянием предметной области и сохранил только инфраструктурную ответственность.
|
||||||
|
|
||||||
|
К началу Build 060.21 в проекте уже существовали:
|
||||||
|
|
||||||
|
- транспортные WebSocket-протоколы;
|
||||||
|
- типизированные Runtime-команды;
|
||||||
|
- типизированные Runtime-события;
|
||||||
|
- модели транспортных сообщений;
|
||||||
|
- независимые подсистемы Trade Stream Consistency и Trade Recovery.
|
||||||
|
|
||||||
|
Однако отсутствовали публичные контракты, связывающие типизированные команды и события с будущей реализацией Runtime Service.
|
||||||
|
|
||||||
|
Главной задачей Build 060.21 стало расширение существующего Runtime Protocol Layer двумя узкими инфраструктурными контрактами:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AcquisitionRuntimeCommandDispatcherProtocol
|
||||||
|
AcquisitionRuntimeEventPublisherProtocol
|
||||||
|
```
|
||||||
|
|
||||||
|
Одновременно были введены точные типовые объединения:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AcquisitionRuntimeCommand
|
||||||
|
AcquisitionRuntimeEvent
|
||||||
|
```
|
||||||
|
|
||||||
|
Build сознательно не создаёт Runtime Service и не меняет поведение существующих компонентов.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Предпосылки
|
||||||
|
|
||||||
|
К началу настоящего Build Runtime Layer уже содержал базовые контракты:
|
||||||
|
|
||||||
|
```text
|
||||||
|
WebSocketTransportProtocol
|
||||||
|
WebSocketSessionProtocol
|
||||||
|
WebSocketSubscriptionManagerProtocol
|
||||||
|
```
|
||||||
|
|
||||||
|
Они описывали:
|
||||||
|
|
||||||
|
- открытие и закрытие WebSocket-соединения;
|
||||||
|
- отправку и получение транспортных сообщений;
|
||||||
|
- жизненный цикл WebSocket-сессии;
|
||||||
|
- восстановление и очистку подписок.
|
||||||
|
|
||||||
|
Также существовали отдельные модели команд:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ConnectCommand
|
||||||
|
DisconnectCommand
|
||||||
|
SubscribeCommand
|
||||||
|
UnsubscribeCommand
|
||||||
|
SendTextCommand
|
||||||
|
SendBinaryCommand
|
||||||
|
```
|
||||||
|
|
||||||
|
и модели событий:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ConnectedEvent
|
||||||
|
DisconnectedEvent
|
||||||
|
ConnectFailedEvent
|
||||||
|
MessageReceivedEvent
|
||||||
|
MessageSentEvent
|
||||||
|
ReconnectStartedEvent
|
||||||
|
ReconnectCompletedEvent
|
||||||
|
ReconnectFailedEvent
|
||||||
|
HeartbeatTimeoutEvent
|
||||||
|
```
|
||||||
|
|
||||||
|
Несмотря на наличие всех перечисленных сущностей, в системе отсутствовал формальный контракт их передачи.
|
||||||
|
|
||||||
|
Не было определено:
|
||||||
|
|
||||||
|
- каким образом команда поступает в Runtime;
|
||||||
|
- каким образом Runtime публикует инфраструктурное событие;
|
||||||
|
- какие типы команд допустимы;
|
||||||
|
- какие типы событий допустимы;
|
||||||
|
- как сохранить независимость Runtime от бизнес-логики Acquisition.
|
||||||
|
|
||||||
|
Именно эту контрактную границу формализует Build 060.21.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Результаты архитектурного аудита
|
||||||
|
|
||||||
|
Перед началом реализации был выполнен аудит следующих компонентов:
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/market_data/acquisition/runtime/websocket_protocol.py
|
||||||
|
src/market_data/acquisition/runtime/runtime_commands.py
|
||||||
|
src/market_data/acquisition/runtime/runtime_events.py
|
||||||
|
src/market_data/acquisition/runtime/transport_messages.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Дополнительно были проанализированы:
|
||||||
|
|
||||||
|
- Runtime unit-тесты;
|
||||||
|
- Trades Feed;
|
||||||
|
- WebSocket Trade Adapter;
|
||||||
|
- Trade Stream Consistency;
|
||||||
|
- Trade Recovery;
|
||||||
|
- Acquisition Service и Registry;
|
||||||
|
- repository-wide зависимости Runtime Protocol Layer.
|
||||||
|
|
||||||
|
Аудит подтвердил, что текущие команды и события уже достаточны для настоящего этапа.
|
||||||
|
|
||||||
|
Следовательно:
|
||||||
|
|
||||||
|
- новые команды не требуются;
|
||||||
|
- новые события не требуются;
|
||||||
|
- существующие WebSocket Protocol не должны изменять ответственность;
|
||||||
|
- Runtime Service не должен создаваться преждевременно;
|
||||||
|
- Consistency и Recovery не должны получать Runtime-зависимости.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Отказ от общего RuntimeServiceProtocol в Build 060.21
|
||||||
|
|
||||||
|
На раннем этапе проектирования рассматривалось создание единого контракта:
|
||||||
|
|
||||||
|
```text
|
||||||
|
RuntimeServiceProtocol
|
||||||
|
```
|
||||||
|
|
||||||
|
Предполагалось включить в него операции жизненного цикла, подписок, отправки сообщений и состояния соединения.
|
||||||
|
|
||||||
|
После аудита данный шаг был признан преждевременным.
|
||||||
|
|
||||||
|
В утверждённой дорожной карте следующий этап определён отдельно:
|
||||||
|
|
||||||
|
```text
|
||||||
|
060.22 Runtime Service Integration
|
||||||
|
```
|
||||||
|
|
||||||
|
Создание полноценного сервисного контракта в Build 060.21 фактически перенесло бы часть ответственности Build 060.22 в текущий этап.
|
||||||
|
|
||||||
|
Поэтому Build 060.21 ограничен только недостающими инфраструктурными контрактами:
|
||||||
|
|
||||||
|
- dispatcher команд;
|
||||||
|
- publisher событий.
|
||||||
|
|
||||||
|
Такое решение сохраняет строгую границу между этапами.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Архитектурное решение
|
||||||
|
|
||||||
|
После завершения Build Runtime Protocol Layer имеет следующий вид.
|
||||||
|
|
||||||
|
```text
|
||||||
|
Acquisition Runtime Commands
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
AcquisitionRuntimeCommandDispatcherProtocol
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Future Runtime Service
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
AcquisitionRuntimeEventPublisherProtocol
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Acquisition Runtime Events
|
||||||
|
```
|
||||||
|
|
||||||
|
Новые Protocol не реализуют поведение.
|
||||||
|
|
||||||
|
Они только формализуют допустимый интерфейс будущих компонентов.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# AcquisitionRuntimeCommand
|
||||||
|
|
||||||
|
В `websocket_protocol.py` введён типовой alias:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AcquisitionRuntimeCommand
|
||||||
|
```
|
||||||
|
|
||||||
|
Он объединяет все допустимые инфраструктурные команды Acquisition Runtime:
|
||||||
|
|
||||||
|
- `ConnectCommand`;
|
||||||
|
- `DisconnectCommand`;
|
||||||
|
- `SubscribeCommand`;
|
||||||
|
- `UnsubscribeCommand`;
|
||||||
|
- `SendTextCommand`;
|
||||||
|
- `SendBinaryCommand`.
|
||||||
|
|
||||||
|
Таким образом будущая реализация dispatcher получает строго ограниченный тип входных данных.
|
||||||
|
|
||||||
|
Она не может принимать:
|
||||||
|
|
||||||
|
- `Trade`;
|
||||||
|
- `Quote`;
|
||||||
|
- `Candle`;
|
||||||
|
- Recovery Request;
|
||||||
|
- произвольный объект приложения.
|
||||||
|
|
||||||
|
Это закрепляет независимость Runtime от предметной области.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# AcquisitionRuntimeEvent
|
||||||
|
|
||||||
|
Также введён типовой alias:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AcquisitionRuntimeEvent
|
||||||
|
```
|
||||||
|
|
||||||
|
Он объединяет все допустимые инфраструктурные события Acquisition Runtime:
|
||||||
|
|
||||||
|
- `ConnectedEvent`;
|
||||||
|
- `DisconnectedEvent`;
|
||||||
|
- `ConnectFailedEvent`;
|
||||||
|
- `MessageReceivedEvent`;
|
||||||
|
- `MessageSentEvent`;
|
||||||
|
- `ReconnectStartedEvent`;
|
||||||
|
- `ReconnectCompletedEvent`;
|
||||||
|
- `ReconnectFailedEvent`;
|
||||||
|
- `HeartbeatTimeoutEvent`.
|
||||||
|
|
||||||
|
Alias сознательно получил префикс `Acquisition`.
|
||||||
|
|
||||||
|
В проекте уже существует отдельная глобальная система событий:
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/runtime_events/
|
||||||
|
```
|
||||||
|
|
||||||
|
с собственной моделью `RuntimeEvent`.
|
||||||
|
|
||||||
|
Использование общего имени внутри Acquisition создало бы неоднозначность и риск ошибочных импортов.
|
||||||
|
|
||||||
|
Поэтому итоговые имена были уточнены:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AcquisitionRuntimeCommand
|
||||||
|
AcquisitionRuntimeEvent
|
||||||
|
```
|
||||||
|
|
||||||
|
Это решение полностью устраняет терминологический конфликт.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# AcquisitionRuntimeCommandDispatcherProtocol
|
||||||
|
|
||||||
|
Добавлен новый публичный контракт:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AcquisitionRuntimeCommandDispatcherProtocol
|
||||||
|
```
|
||||||
|
|
||||||
|
Protocol определяет одну операцию:
|
||||||
|
|
||||||
|
```text
|
||||||
|
dispatch(command: AcquisitionRuntimeCommand) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
Метод является асинхронным.
|
||||||
|
|
||||||
|
Dispatcher отвечает только за передачу одной типизированной инфраструктурной команды в Runtime.
|
||||||
|
|
||||||
|
Он не определяет:
|
||||||
|
|
||||||
|
- внутреннюю маршрутизацию;
|
||||||
|
- порядок исполнения;
|
||||||
|
- повторные попытки;
|
||||||
|
- обработку ошибок;
|
||||||
|
- жизненный цикл сессии;
|
||||||
|
- реакцию бизнес-компонентов.
|
||||||
|
|
||||||
|
Все перечисленные обязанности относятся к будущей реализации Runtime Service.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# AcquisitionRuntimeEventPublisherProtocol
|
||||||
|
|
||||||
|
Добавлен второй публичный контракт:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AcquisitionRuntimeEventPublisherProtocol
|
||||||
|
```
|
||||||
|
|
||||||
|
Protocol определяет одну операцию:
|
||||||
|
|
||||||
|
```text
|
||||||
|
publish(event: AcquisitionRuntimeEvent) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
Метод также является асинхронным.
|
||||||
|
|
||||||
|
Publisher отвечает исключительно за публикацию уже произошедшего инфраструктурного факта.
|
||||||
|
|
||||||
|
Он не определяет:
|
||||||
|
|
||||||
|
- список подписчиков;
|
||||||
|
- механизм доставки;
|
||||||
|
- очередь событий;
|
||||||
|
- обработку ошибок потребителей;
|
||||||
|
- реакцию Trades Feed;
|
||||||
|
- запуск Recovery;
|
||||||
|
- правила reconnect.
|
||||||
|
|
||||||
|
Эти вопросы относятся к последующим Build.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Почему Protocol расположены в websocket_protocol.py
|
||||||
|
|
||||||
|
В рамках настоящего Build новые контракты добавлены в существующий файл:
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/market_data/acquisition/runtime/websocket_protocol.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Причины данного решения:
|
||||||
|
|
||||||
|
- файл уже является центральной точкой Runtime Protocol Layer;
|
||||||
|
- все текущие Protocol относятся к WebSocket Runtime;
|
||||||
|
- Build ограничен двумя небольшими контрактами;
|
||||||
|
- создание нового каталога или дополнительной иерархии файлов было бы преждевременным;
|
||||||
|
- существующая структура проекта сохраняется без реорганизации.
|
||||||
|
|
||||||
|
При дальнейшем расширении Runtime Protocol Layer отдельный файл может быть введён отдельным согласованным Build, если объём контрактов действительно потребует этого.
|
||||||
|
|
||||||
|
Настоящий Build не выполняет структурную реорганизацию каталогов.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Разделение ответственности
|
||||||
|
|
||||||
|
После завершения Build окончательно закреплены следующие границы.
|
||||||
|
|
||||||
|
## Runtime Commands
|
||||||
|
|
||||||
|
Команды являются неизменяемыми инфраструктурными намерениями.
|
||||||
|
|
||||||
|
Они описывают, что необходимо выполнить.
|
||||||
|
|
||||||
|
Они не выполняют операцию самостоятельно.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Command Dispatcher
|
||||||
|
|
||||||
|
Dispatcher принимает команду и передаёт её будущей реализации Runtime.
|
||||||
|
|
||||||
|
Он не содержит бизнес-логики.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Runtime Events
|
||||||
|
|
||||||
|
События являются неизменяемыми инфраструктурными фактами.
|
||||||
|
|
||||||
|
Они описывают уже произошедшее состояние транспорта.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Event Publisher
|
||||||
|
|
||||||
|
Publisher передаёт событие заинтересованным потребителям.
|
||||||
|
|
||||||
|
Он не определяет реакцию потребителя.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WebSocket Transport
|
||||||
|
|
||||||
|
Transport продолжает отвечать только за низкоуровневое соединение и транспортные сообщения.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WebSocket Session
|
||||||
|
|
||||||
|
Session продолжает отвечать за жизненный цикл WebSocket-сессии.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Subscription Manager
|
||||||
|
|
||||||
|
Subscription Manager продолжает отвечать за восстановление и очистку активных подписок.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Изменённые файлы
|
||||||
|
|
||||||
|
В рамках Build изменены только два файла.
|
||||||
|
|
||||||
|
## Runtime Protocol Layer
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/market_data/acquisition/runtime/websocket_protocol.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавлены:
|
||||||
|
|
||||||
|
- `AcquisitionRuntimeCommand`;
|
||||||
|
- `AcquisitionRuntimeEvent`;
|
||||||
|
- `AcquisitionRuntimeCommandDispatcherProtocol`;
|
||||||
|
- `AcquisitionRuntimeEventPublisherProtocol`.
|
||||||
|
|
||||||
|
Существующие Protocol сохранены без изменения поведения:
|
||||||
|
|
||||||
|
- `WebSocketTransportProtocol`;
|
||||||
|
- `WebSocketSessionProtocol`;
|
||||||
|
- `WebSocketSubscriptionManagerProtocol`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Unit-тесты Runtime Protocol
|
||||||
|
|
||||||
|
```text
|
||||||
|
tests/unit/market_data/acquisition/runtime/test_websocket_protocol.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Добавлены тестовые реализации:
|
||||||
|
|
||||||
|
- `FakeRuntimeCommandDispatcher`;
|
||||||
|
- `FakeRuntimeEventPublisher`.
|
||||||
|
|
||||||
|
Добавлены проверки:
|
||||||
|
|
||||||
|
- полная реализация dispatcher соответствует Protocol;
|
||||||
|
- полная реализация publisher соответствует Protocol;
|
||||||
|
- неполная реализация dispatcher не соответствует Protocol;
|
||||||
|
- неполная реализация publisher не соответствует Protocol.
|
||||||
|
|
||||||
|
Все существующие тесты WebSocket Protocol сохранены.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Файлы, которые не изменялись
|
||||||
|
|
||||||
|
Аудит подтвердил отсутствие необходимости менять:
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/market_data/acquisition/runtime/runtime_commands.py
|
||||||
|
src/market_data/acquisition/runtime/runtime_events.py
|
||||||
|
src/market_data/acquisition/runtime/transport_messages.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Их существующее поведение полностью соответствует новому Protocol Layer.
|
||||||
|
|
||||||
|
Также не изменялись:
|
||||||
|
|
||||||
|
- Runtime Supervisor;
|
||||||
|
- Reconnect;
|
||||||
|
- Scheduler;
|
||||||
|
- Heartbeat;
|
||||||
|
- Trades Feed;
|
||||||
|
- WebSocket Adapters;
|
||||||
|
- Trade Stream Consistency;
|
||||||
|
- Trade Recovery;
|
||||||
|
- Acquisition Service;
|
||||||
|
- Acquisition Registry.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Unit-тестирование
|
||||||
|
|
||||||
|
Новый Runtime Protocol Layer был покрыт структурными unit-тестами.
|
||||||
|
|
||||||
|
Проверялись следующие сценарии:
|
||||||
|
|
||||||
|
- реализация WebSocket Transport удовлетворяет Protocol;
|
||||||
|
- реализация WebSocket Session удовлетворяет Protocol;
|
||||||
|
- реализация Subscription Manager удовлетворяет Protocol;
|
||||||
|
- реализация Command Dispatcher удовлетворяет Protocol;
|
||||||
|
- реализация Event Publisher удовлетворяет Protocol;
|
||||||
|
- неполный Transport отклоняется;
|
||||||
|
- неполный Command Dispatcher отклоняется;
|
||||||
|
- неполный Event Publisher отклоняется.
|
||||||
|
|
||||||
|
Результат локального теста:
|
||||||
|
|
||||||
|
```text
|
||||||
|
8 passed
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Регрессионное тестирование Runtime Layer
|
||||||
|
|
||||||
|
После добавления новых контрактов выполнен полный прогон тестов каталога Runtime.
|
||||||
|
|
||||||
|
Проверены:
|
||||||
|
|
||||||
|
- Runtime Commands;
|
||||||
|
- Runtime Events;
|
||||||
|
- Transport Messages;
|
||||||
|
- WebSocket Protocols;
|
||||||
|
- новые dispatcher и publisher Protocol.
|
||||||
|
|
||||||
|
Результат:
|
||||||
|
|
||||||
|
```text
|
||||||
|
34 passed
|
||||||
|
```
|
||||||
|
|
||||||
|
Это подтверждает, что расширение Protocol Layer не изменило существующее поведение Runtime.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Расширенное регрессионное тестирование
|
||||||
|
|
||||||
|
Дополнительно выполнен совместный прогон трёх связанных подсистем:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Runtime
|
||||||
|
Consistency
|
||||||
|
Recovery
|
||||||
|
```
|
||||||
|
|
||||||
|
Результат:
|
||||||
|
|
||||||
|
```text
|
||||||
|
136 passed
|
||||||
|
```
|
||||||
|
|
||||||
|
Тем самым подтверждено:
|
||||||
|
|
||||||
|
- Runtime Protocol Layer работает корректно;
|
||||||
|
- Trade Stream Consistency не затронута;
|
||||||
|
- Trade Stream State Store не затронут;
|
||||||
|
- Trade Recovery не затронута;
|
||||||
|
- новые контракты не создали циклических или скрытых зависимостей.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Repository-wide аудит имён
|
||||||
|
|
||||||
|
После первоначальной реализации был выполнен поиск по репозиторию.
|
||||||
|
|
||||||
|
Аудит выявил существующую глобальную модель:
|
||||||
|
|
||||||
|
```text
|
||||||
|
src.runtime_events.models.RuntimeEvent
|
||||||
|
```
|
||||||
|
|
||||||
|
Поэтому первоначальные общие имена:
|
||||||
|
|
||||||
|
```text
|
||||||
|
RuntimeCommand
|
||||||
|
RuntimeEvent
|
||||||
|
RuntimeCommandDispatcherProtocol
|
||||||
|
RuntimeEventPublisherProtocol
|
||||||
|
```
|
||||||
|
|
||||||
|
были уточнены.
|
||||||
|
|
||||||
|
Итоговые имена:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AcquisitionRuntimeCommand
|
||||||
|
AcquisitionRuntimeEvent
|
||||||
|
AcquisitionRuntimeCommandDispatcherProtocol
|
||||||
|
AcquisitionRuntimeEventPublisherProtocol
|
||||||
|
```
|
||||||
|
|
||||||
|
Это разделяет:
|
||||||
|
|
||||||
|
- Acquisition Runtime transport events;
|
||||||
|
- глобальные application runtime events.
|
||||||
|
|
||||||
|
Терминологическая неоднозначность полностью устранена.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Обратная совместимость
|
||||||
|
|
||||||
|
Build сохраняет полную обратную совместимость.
|
||||||
|
|
||||||
|
Не изменились:
|
||||||
|
|
||||||
|
- сигнатуры существующих WebSocket Protocol;
|
||||||
|
- модели Runtime Commands;
|
||||||
|
- модели Runtime Events;
|
||||||
|
- модели Transport Messages;
|
||||||
|
- алгоритмы Stream Consistency;
|
||||||
|
- State Store;
|
||||||
|
- Recovery Pipeline;
|
||||||
|
- Trades Feed;
|
||||||
|
- каноническая модель `Trade`.
|
||||||
|
|
||||||
|
Новые контракты являются исключительно расширением публичного Protocol Layer.
|
||||||
|
|
||||||
|
Существующие реализации не обязаны реализовывать новые Protocol до момента их подключения в последующих Build.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Производительность
|
||||||
|
|
||||||
|
Build не добавляет runtime-операций и не влияет на производительность системы.
|
||||||
|
|
||||||
|
Типовые alias существуют только на уровне статической типизации.
|
||||||
|
|
||||||
|
Protocol также не создают дополнительного runtime-поведения, за исключением стандартной structural runtime-проверки через `@runtime_checkable`, уже применявшейся в существующем коде.
|
||||||
|
|
||||||
|
Следовательно Build не влияет на:
|
||||||
|
|
||||||
|
- задержку обработки сообщений;
|
||||||
|
- пропускную способность WebSocket;
|
||||||
|
- использование памяти;
|
||||||
|
- обработку Trade Stream;
|
||||||
|
- Recovery Pipeline.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Подтверждённые архитектурные инварианты
|
||||||
|
|
||||||
|
## Runtime не знает предметную область
|
||||||
|
|
||||||
|
Новые контракты принимают только Acquisition Runtime Commands и Events.
|
||||||
|
|
||||||
|
Они не используют модели Trade, Quote, Candle или Order Book.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Consistency не зависит от Runtime
|
||||||
|
|
||||||
|
`TradeStreamConsistencyController` продолжает зависеть только от собственного State Store.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recovery не зависит от Runtime
|
||||||
|
|
||||||
|
`TradeRecoveryController` продолжает использовать только `TradeStreamConsistencyProtocol`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Команды отделены от исполнения
|
||||||
|
|
||||||
|
Command-модели описывают намерение.
|
||||||
|
|
||||||
|
Dispatcher предоставляет контракт передачи команды.
|
||||||
|
|
||||||
|
Реализация выполнения отсутствует в настоящем Build.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## События отделены от реакции
|
||||||
|
|
||||||
|
Event-модели описывают инфраструктурный факт.
|
||||||
|
|
||||||
|
Publisher предоставляет контракт публикации.
|
||||||
|
|
||||||
|
Реакция потребителей отсутствует в настоящем Build.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Runtime Service не входит в Scope
|
||||||
|
|
||||||
|
Настоящий Build не создаёт сервисную реализацию и не определяет полный сервисный API.
|
||||||
|
|
||||||
|
Эта ответственность закреплена за Build 060.22.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Что не входит в Scope Build
|
||||||
|
|
||||||
|
Настоящий Build сознательно ограничен расширением Runtime Protocol Layer.
|
||||||
|
|
||||||
|
В него не входят:
|
||||||
|
|
||||||
|
- реализация Command Dispatcher;
|
||||||
|
- реализация Event Publisher;
|
||||||
|
- Runtime Service;
|
||||||
|
- Runtime Supervisor;
|
||||||
|
- запуск и остановка Runtime;
|
||||||
|
- обработка команд;
|
||||||
|
- доставка событий подписчикам;
|
||||||
|
- очередь событий;
|
||||||
|
- Reconnect orchestration;
|
||||||
|
- Heartbeat orchestration;
|
||||||
|
- Scheduler;
|
||||||
|
- интеграция Trades Feed;
|
||||||
|
- интеграция Acquisition Service;
|
||||||
|
- автоматический запуск Recovery;
|
||||||
|
- восстановление подписок после reconnect;
|
||||||
|
- Composition Root.
|
||||||
|
|
||||||
|
Отсутствие перечисленных компонентов является осознанной границей Build.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Архитектурное значение Build
|
||||||
|
|
||||||
|
Несмотря на небольшой объём изменения production-кода, Build 060.21 является важным контрактным этапом.
|
||||||
|
|
||||||
|
До него Runtime Layer обладал моделями команд и событий, но не имел формального интерфейса их передачи.
|
||||||
|
|
||||||
|
После завершения Build появляются две стабильные точки расширения:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AcquisitionRuntimeCommandDispatcherProtocol
|
||||||
|
AcquisitionRuntimeEventPublisherProtocol
|
||||||
|
```
|
||||||
|
|
||||||
|
Именно через них последующие реализации смогут:
|
||||||
|
|
||||||
|
- принимать инфраструктурные команды;
|
||||||
|
- публиковать инфраструктурные события;
|
||||||
|
- сохранять независимость от конкретного транспорта;
|
||||||
|
- оставаться изолированными от предметной области Market Data Acquisition.
|
||||||
|
|
||||||
|
Это создаёт основу для Build 060.22 без преждевременного внедрения сервисной реализации.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Связь с последующими Build
|
||||||
|
|
||||||
|
## Build 060.22 — Runtime Service Integration
|
||||||
|
|
||||||
|
Будущая реализация Runtime Service должна использовать новые Protocol как публичные границы передачи команд и событий.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Build 060.23 — Acquisition Integration
|
||||||
|
|
||||||
|
Acquisition Layer сможет использовать Runtime Service через утверждённые контракты без прямой зависимости от внутренней реализации Runtime.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Build 060.24 — Reconnect & Runtime Recovery
|
||||||
|
|
||||||
|
Reconnect, resubscribe и запуск Recovery смогут строиться на типизированных командах и событиях без изменения существующих контрактов Consistency и Recovery.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Build 060.25 — Integration & Regression
|
||||||
|
|
||||||
|
Будет выполнена полная проверка взаимодействия Runtime, Acquisition, Consistency и Recovery.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Заключение
|
||||||
|
|
||||||
|
Build 060.21 завершает формирование базового Runtime Protocol Layer внутри подсистемы **Market Data Acquisition**.
|
||||||
|
|
||||||
|
В рамках этапа не создавалась новая реализация и не менялось функциональное поведение системы.
|
||||||
|
|
||||||
|
Вместо этого были введены две узкие инфраструктурные границы:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AcquisitionRuntimeCommandDispatcherProtocol
|
||||||
|
AcquisitionRuntimeEventPublisherProtocol
|
||||||
|
```
|
||||||
|
|
||||||
|
Они дополняют уже существующие:
|
||||||
|
|
||||||
|
```text
|
||||||
|
WebSocketTransportProtocol
|
||||||
|
WebSocketSessionProtocol
|
||||||
|
WebSocketSubscriptionManagerProtocol
|
||||||
|
```
|
||||||
|
|
||||||
|
и создают полный контрактный фундамент для будущего Runtime Service.
|
||||||
|
|
||||||
|
Build сохранил независимость:
|
||||||
|
|
||||||
|
- Runtime от бизнес-моделей;
|
||||||
|
- Consistency от Runtime;
|
||||||
|
- Recovery от Runtime;
|
||||||
|
- Feed от внутренней реализации транспорта.
|
||||||
|
|
||||||
|
Все изменения подтверждены unit- и regression-тестами.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Итог Build
|
||||||
|
|
||||||
|
После завершения Build 060.21 система обладает следующими возможностями.
|
||||||
|
|
||||||
|
✓ Определён полный типовой набор Acquisition Runtime Commands.
|
||||||
|
|
||||||
|
✓ Определён полный типовой набор Acquisition Runtime Events.
|
||||||
|
|
||||||
|
✓ Введён публичный Protocol передачи Runtime-команд.
|
||||||
|
|
||||||
|
✓ Введён публичный Protocol публикации Runtime-событий.
|
||||||
|
|
||||||
|
✓ Устранён терминологический конфликт с глобальной подсистемой `src/runtime_events`.
|
||||||
|
|
||||||
|
✓ Существующие Runtime Commands и Events сохранены без изменений.
|
||||||
|
|
||||||
|
✓ Consistency и Recovery сохранены без изменений.
|
||||||
|
|
||||||
|
✓ Runtime regression завершён результатом `34 passed`.
|
||||||
|
|
||||||
|
✓ Расширенный regression завершён результатом `136 passed`.
|
||||||
|
|
||||||
|
Build **060.21 — Runtime Protocol Integration** считается полностью завершённым и готовым к фиксации в Git.
|
||||||
931
docs/migrations/build_060_21_architecture.md
Normal file
931
docs/migrations/build_060_21_architecture.md
Normal file
@@ -0,0 +1,931 @@
|
|||||||
|
# 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.22–060.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.
|
||||||
Reference in New Issue
Block a user