2463 lines
70 KiB
Markdown
2463 lines
70 KiB
Markdown
# Build 060.20 — Trade Runtime Architecture
|
||
|
||
**Статус:** Accepted
|
||
|
||
**Тип документа:** Architecture Specification
|
||
|
||
**Build:** 060.20
|
||
**Ветка:** Trades Feed (Time & Sales)
|
||
**Документ:** `build_060_20_architecture.md`
|
||
**Предыдущие рабочие названия:** Trade Recovery Registry, Trade Runtime Registry
|
||
|
||
**Связанные документы:**
|
||
|
||
- [Build 060.20 Engineering Migration Report](build_060_20.md);
|
||
- [Build 060.19 Architecture](build_060_19_architecture.md);
|
||
- [Build 060.18 Architecture](build_060_18_architecture.md).
|
||
|
||
---
|
||
|
||
# Назначение документа
|
||
|
||
Настоящий документ является официальной архитектурной спецификацией Build **060.20 — Trade Runtime Architecture**.
|
||
|
||
Документ определяет:
|
||
|
||
- архитектурную модель Trade Runtime;
|
||
- границы Trade Runtime;
|
||
- состав Runtime-модулей текущего Build;
|
||
- ответственность `TradeRuntimeRegistry`;
|
||
- модель владения жизненным циклом Runtime-компонентов;
|
||
- модель владения бизнес-состоянием Canonical Trade Stream;
|
||
- границы интеграции Runtime и Acquisition;
|
||
- правила Dependency Injection;
|
||
- файловый план;
|
||
- стратегию тестирования;
|
||
- критерии завершения Build.
|
||
|
||
Документ является единственным источником истины для реализации Build 060.20.
|
||
|
||
Все решения, зафиксированные настоящей спецификацией, считаются утверждёнными до начала реализации.
|
||
|
||
Изменение этих решений во время разработки допускается только после:
|
||
|
||
1. остановки реализации;
|
||
2. повторного архитектурного анализа;
|
||
3. подготовки отдельного ADR;
|
||
4. обновления настоящего документа.
|
||
|
||
---
|
||
|
||
# Статус Build
|
||
|
||
Build 060.20 является непосредственным продолжением серии Build 060, посвящённой построению подсистемы получения и сопровождения потока сделок:
|
||
|
||
```text
|
||
Trades Feed / Time & Sales
|
||
```
|
||
|
||
К началу Build в системе уже существуют:
|
||
|
||
- каноническая модель `Trade`;
|
||
- Trades Feed;
|
||
- Trade Stream Consistency;
|
||
- `TradeStreamConsistencyController`;
|
||
- Trade Recovery;
|
||
- `TradeRecoveryController`;
|
||
- REST Recovery Pipeline;
|
||
- Runtime Protocol.
|
||
|
||
Система уже умеет:
|
||
|
||
- получать документы сделок из REST;
|
||
- преобразовывать транспортные документы в каноническую модель `Trade`;
|
||
- контролировать порядок канонического потока;
|
||
- исключать повторную публикацию сделок;
|
||
- обнаруживать конфликтующие повторы;
|
||
- обнаруживать нарушения непрерывности потока;
|
||
- восстанавливать отсутствующие участки посредством Recovery.
|
||
|
||
Однако предыдущие Build не определяют единую архитектурную модель существования долгоживущих компонентов Trade Stream.
|
||
|
||
В частности, ещё не определено:
|
||
|
||
- где создаются stateful-компоненты;
|
||
- кто владеет их жизненным циклом;
|
||
- как обеспечивается повторное использование экземпляров;
|
||
- как разные Runtime-модули получают доступ к общему состоянию потока;
|
||
- где проходит граница между Acquisition и Runtime;
|
||
- как в дальнейшем подключать новые Runtime-модули без создания отдельных Registry.
|
||
|
||
Build 060.20 закрывает именно эту архитектурную задачу.
|
||
|
||
---
|
||
|
||
# Предпосылки
|
||
|
||
Настоящий Build опирается на архитектурные решения, принятые в предыдущих этапах.
|
||
|
||
---
|
||
|
||
## Build 057
|
||
|
||
Определены базовые принципы новой архитектуры Market Data Acquisition.
|
||
|
||
Разделены:
|
||
|
||
- транспортный уровень;
|
||
- слой преобразования;
|
||
- каноническая доменная модель;
|
||
- интеграционные границы.
|
||
|
||
Acquisition построен преимущественно из stateless-компонентов.
|
||
|
||
---
|
||
|
||
## Build 060.1
|
||
|
||
Введена единая каноническая модель:
|
||
|
||
```text
|
||
Trade
|
||
```
|
||
|
||
Все источники сделок обязаны приводить входные данные к одной Domain Model.
|
||
|
||
Источник данных не должен влиять на последующую обработку сделки.
|
||
|
||
---
|
||
|
||
## Build 060.17
|
||
|
||
Построен Trades Feed.
|
||
|
||
Получение сделок отделено от конкретной транспортной реализации.
|
||
|
||
Feed отвечает за получение и публикацию канонических сделок, но не является владельцем долгоживущего состояния потока.
|
||
|
||
---
|
||
|
||
## Build 060.18
|
||
|
||
Введён:
|
||
|
||
```text
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
Он стал первым явно stateful-компонентом новой подсистемы Trades Feed.
|
||
|
||
Контроллер определён как единственный владелец бизнес-состояния Canonical Trade Stream.
|
||
|
||
Он отвечает за:
|
||
|
||
- порядок сделок;
|
||
- дедупликацию;
|
||
- обнаружение конфликтующих повторов;
|
||
- обнаружение разрывов;
|
||
- сохранение текущего состояния потока.
|
||
|
||
Build 060.18 определил владельца бизнес-состояния, но сознательно не определил владельца жизненного цикла самого Controller.
|
||
|
||
---
|
||
|
||
## Build 060.19
|
||
|
||
Введён:
|
||
|
||
```text
|
||
TradeRecoveryController
|
||
```
|
||
|
||
Он отвечает за выполнение Recovery Pipeline и восстановление отсутствующих участков потока.
|
||
|
||
Recovery использует существующий `TradeStreamConsistencyController`, но не должен владеть его состоянием или жизненным циклом.
|
||
|
||
Build 060.19 определил операцию Recovery, но сознательно не формализовал Runtime, внутри которого эта операция выполняется.
|
||
|
||
---
|
||
|
||
# Архитектурная проблема
|
||
|
||
Предыдущая архитектура Market Data Acquisition основана преимущественно на короткоживущих stateless-компонентах.
|
||
|
||
Типичный Acquisition Pipeline выглядит следующим образом.
|
||
|
||
```text
|
||
Source
|
||
|
||
↓
|
||
|
||
Parser
|
||
|
||
↓
|
||
|
||
Validation
|
||
|
||
↓
|
||
|
||
Mapper
|
||
|
||
↓
|
||
|
||
Handler
|
||
|
||
↓
|
||
|
||
Canonical Model
|
||
```
|
||
|
||
Такие компоненты могут:
|
||
|
||
- создаваться перед выполнением операции;
|
||
- использоваться для обработки данных;
|
||
- уничтожаться после завершения операции.
|
||
|
||
Их повторное создание не приводит к потере бизнес-состояния.
|
||
|
||
---
|
||
|
||
## Появление stateful-компонентов
|
||
|
||
`TradeStreamConsistencyController` не соответствует такой модели жизненного цикла.
|
||
|
||
Он хранит накопленное состояние Canonical Trade Stream.
|
||
|
||
Например:
|
||
|
||
- последнюю принятую сделку;
|
||
- уже обработанные идентификаторы;
|
||
- сведения, необходимые для контроля порядка;
|
||
- сведения, необходимые для обнаружения разрыва;
|
||
- другую информацию, определённую Build 060.18.
|
||
|
||
Если при каждой операции создаётся новый экземпляр Controller, накопленное состояние теряется.
|
||
|
||
В результате:
|
||
|
||
- последовательные вызовы перестают работать с единым потоком;
|
||
- дедупликация ограничивается одним вызовом;
|
||
- контроль порядка начинается заново;
|
||
- Recovery не продолжает уже существующий Canonical Trade Stream;
|
||
- REST и будущий WebSocket могут получить независимые состояния;
|
||
- система перестаёт иметь единую каноническую картину Trade Stream.
|
||
|
||
Следовательно, stateful-компонент не может принадлежать жизненному циклу отдельной Acquisition-операции.
|
||
|
||
---
|
||
|
||
## Недостаточность модели Recovery Runtime
|
||
|
||
Первоначально проблема рассматривалась как необходимость создания:
|
||
|
||
```text
|
||
Recovery Runtime
|
||
```
|
||
|
||
Однако эта модель является слишком узкой.
|
||
|
||
`TradeStreamConsistencyController` необходим не только Recovery.
|
||
|
||
Он сопровождает Canonical Trade Stream независимо от источника и способа доставки сделок.
|
||
|
||
Его потенциальными потребителями являются:
|
||
|
||
- REST Recovery;
|
||
- WebSocket Trades Feed;
|
||
- Gap Detection;
|
||
- Stream Monitoring;
|
||
- Recovery Scheduler;
|
||
- другие будущие Runtime-модули.
|
||
|
||
Следовательно, состояние и жизненный цикл принадлежат не операции Recovery.
|
||
|
||
Они принадлежат подсистеме сопровождения Trade Stream.
|
||
|
||
---
|
||
|
||
# Основная идея Build
|
||
|
||
Build 060.20 вводит новый официальный архитектурный уровень:
|
||
|
||
```text
|
||
Trade Runtime
|
||
```
|
||
|
||
Trade Runtime существует независимо от:
|
||
|
||
- отдельных REST-запросов;
|
||
- отдельных Recovery-вызовов;
|
||
- Feed-вызовов;
|
||
- транспортного источника;
|
||
- конкретной операции Acquisition.
|
||
|
||
Trade Runtime объединяет долгоживущие компоненты, необходимые для сопровождения единого Canonical Trade Stream.
|
||
|
||
---
|
||
|
||
# Разделение жизненных циклов
|
||
|
||
Build формально разделяет два независимых жизненных цикла.
|
||
|
||
---
|
||
|
||
## Acquisition Lifetime
|
||
|
||
```text
|
||
создание операции
|
||
|
||
↓
|
||
|
||
получение данных
|
||
|
||
↓
|
||
|
||
преобразование данных
|
||
|
||
↓
|
||
|
||
публикация результата
|
||
|
||
↓
|
||
|
||
завершение операции
|
||
```
|
||
|
||
Acquisition-компоненты могут быть короткоживущими.
|
||
|
||
Они не должны владеть состоянием непрерывного Trade Stream.
|
||
|
||
---
|
||
|
||
## Trade Runtime Lifetime
|
||
|
||
```text
|
||
создание Runtime
|
||
|
||
↓
|
||
|
||
регистрация Runtime-компонентов
|
||
|
||
↓
|
||
|
||
многократное использование
|
||
|
||
↓
|
||
|
||
обслуживание Trade Stream
|
||
|
||
↓
|
||
|
||
завершение процесса
|
||
```
|
||
|
||
Trade Runtime существует дольше любой отдельной Acquisition-операции.
|
||
|
||
Количество вызовов Feed или Recovery не должно влиять на количество экземпляров Runtime-компонентов.
|
||
|
||
---
|
||
|
||
# Trade Runtime Model
|
||
|
||
## Определение
|
||
|
||
**Trade Runtime** — это инфраструктурная подсистема долгоживущих компонентов, обеспечивающих сопровождение единого Canonical Trade Stream в течение жизни процесса.
|
||
|
||
Trade Runtime отвечает за существование и доступность Runtime-компонентов.
|
||
|
||
Он не является:
|
||
|
||
- источником данных;
|
||
- Feed;
|
||
- Handler;
|
||
- транспортным адаптером;
|
||
- Recovery-операцией;
|
||
- владельцем канонической бизнес-модели `Trade`;
|
||
- хранилищем бизнес-логики Acquisition.
|
||
|
||
---
|
||
|
||
## Состав Trade Runtime в текущем Build
|
||
|
||
В рамках Build 060.20 Trade Runtime включает два существующих функциональных модуля.
|
||
|
||
```text
|
||
Trade Runtime
|
||
│
|
||
├── Stream Consistency Module
|
||
│ └── TradeStreamConsistencyController
|
||
│
|
||
└── Recovery Module
|
||
└── TradeRecoveryController
|
||
```
|
||
|
||
Build не переносит бизнес-логику этих компонентов.
|
||
|
||
Build изменяет только модель их создания, хранения, получения и повторного использования.
|
||
|
||
---
|
||
|
||
## Stream Consistency Module
|
||
|
||
Stream Consistency Module отвечает за согласованность Canonical Trade Stream.
|
||
|
||
Его основным компонентом является:
|
||
|
||
```text
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
Он остаётся единственным владельцем бизнес-состояния потока.
|
||
|
||
Build 060.20 не изменяет его бизнес-ответственность.
|
||
|
||
---
|
||
|
||
## Recovery Module
|
||
|
||
Recovery Module отвечает за восстановление отсутствующих участков Trade Stream.
|
||
|
||
Его основным компонентом является:
|
||
|
||
```text
|
||
TradeRecoveryController
|
||
```
|
||
|
||
Recovery является одним из модулей Trade Runtime.
|
||
|
||
Он не является:
|
||
|
||
- самим Runtime;
|
||
- владельцем Runtime;
|
||
- владельцем состояния потока;
|
||
- владельцем жизненного цикла Consistency Controller.
|
||
|
||
---
|
||
|
||
## Возможное дальнейшее расширение
|
||
|
||
В последующих Build Trade Runtime может быть расширен новыми модулями.
|
||
|
||
```text
|
||
Trade Runtime
|
||
│
|
||
├── Stream Consistency Module
|
||
├── Recovery Module
|
||
├── Gap Detection Module
|
||
├── Recovery Scheduling Module
|
||
├── Stream Monitoring Module
|
||
└── другие Runtime-модули
|
||
```
|
||
|
||
Build 060.20 не реализует эти будущие модули.
|
||
|
||
Их перечисление определяет только допустимое направление архитектурного расширения.
|
||
|
||
---
|
||
|
||
# TradeRuntimeRegistry
|
||
|
||
Для управления доступом к долгоживущим компонентам Build вводит:
|
||
|
||
```text
|
||
TradeRuntimeRegistry
|
||
```
|
||
|
||
`TradeRuntimeRegistry` является инфраструктурным реестром компонентов Trade Runtime.
|
||
|
||
Он становится единой точкой доступа к зарегистрированным Runtime-компонентам.
|
||
|
||
Концептуально:
|
||
|
||
```text
|
||
TradeRuntimeRegistry
|
||
│
|
||
├── TradeStreamConsistencyController
|
||
└── TradeRecoveryController
|
||
```
|
||
|
||
Registry не превращает компоненты в единый объект с общей бизнес-логикой.
|
||
|
||
Каждый Runtime-компонент сохраняет:
|
||
|
||
- собственную ответственность;
|
||
- собственный публичный контракт;
|
||
- собственные зависимости;
|
||
- собственную область состояния.
|
||
|
||
Registry обеспечивает только их корректное существование и предоставление.
|
||
|
||
---
|
||
|
||
# Цель Build
|
||
|
||
Цель Build 060.20 — сформировать архитектуру Trade Runtime как самостоятельной инфраструктурной подсистемы Dzentra.
|
||
|
||
В рамках данного Build определяется:
|
||
|
||
* архитектура Runtime;
|
||
* Runtime Layer;
|
||
* Runtime-модули;
|
||
* TradeRuntimeRegistry;
|
||
* модель владения жизненным циклом;
|
||
* модель владения бизнес-состоянием;
|
||
* архитектурные инварианты Runtime.
|
||
|
||
---
|
||
|
||
# Что НЕ входит в Scope Build
|
||
|
||
Настоящий Build сознательно НЕ реализует:
|
||
|
||
- окончательный Composition Root;
|
||
- объединение существующих `service.py`;
|
||
- изменение архитектуры Acquisition;
|
||
- изменение архитектуры Feed;
|
||
- изменение архитектуры Handler;
|
||
- изменение Runtime Protocol;
|
||
- сохранение Runtime между перезапусками процесса;
|
||
- распределённый Runtime;
|
||
- поддержку нескольких процессов;
|
||
- Runtime для других доменных подсистем;
|
||
- интеграцию WebSocket Trades Feed;
|
||
- Gap Detection;
|
||
- Runtime Scheduler;
|
||
- Stream Monitoring;
|
||
- Runtime Metrics;
|
||
- Runtime Health Check;
|
||
- Runtime Lifecycle Manager.
|
||
|
||
Все перечисленные задачи относятся к следующим Build серии 060.
|
||
|
||
Build 060.20 отвечает исключительно за формирование архитектуры локального Trade Runtime.
|
||
|
||
---
|
||
|
||
# Архитектурные принципы
|
||
|
||
Настоящий Build вводит фундаментальные принципы построения Runtime-подсистем Dzentra.
|
||
|
||
Все последующие Runtime должны соответствовать данным правилам.
|
||
|
||
---
|
||
|
||
## 1. Runtime Before Acquisition
|
||
|
||
Любой долгоживущий компонент принадлежит Runtime.
|
||
|
||
Acquisition никогда не создаёт Runtime самостоятельно.
|
||
|
||
Acquisition только использует уже существующие Runtime-компоненты.
|
||
|
||
---
|
||
|
||
## 2. Stateless Acquisition
|
||
|
||
Подсистема Acquisition полностью сохраняет архитектуру предыдущих Build.
|
||
|
||
Stateless остаются:
|
||
|
||
- Source;
|
||
- Parser;
|
||
- Validation;
|
||
- Mapper;
|
||
- Handler;
|
||
- Feed.
|
||
|
||
Build 060.20 не изменяет данное правило.
|
||
|
||
---
|
||
|
||
## 3. Runtime Owns Lifetime
|
||
|
||
Trade Runtime является единственным владельцем жизненного цикла Runtime-компонентов.
|
||
|
||
Никакой Runtime-компонент не имеет права самостоятельно определять собственное существование.
|
||
|
||
---
|
||
|
||
## 4. Business State Owns Itself
|
||
|
||
Жизненный цикл компонентов и бизнес-состояние являются независимыми понятиями.
|
||
|
||
Trade Runtime отвечает за существование компонентов.
|
||
|
||
Каждый Runtime-модуль самостоятельно отвечает за собственное бизнес-состояние.
|
||
|
||
---
|
||
|
||
## 5. Single Runtime Instance
|
||
|
||
Каждый Runtime-компонент существует в единственном экземпляре.
|
||
|
||
Количество Recovery-вызовов,
|
||
|
||
Feed-вызовов,
|
||
|
||
или других Runtime-операций
|
||
|
||
не влияет на количество Runtime-компонентов.
|
||
|
||
---
|
||
|
||
## 6. Runtime Reuse
|
||
|
||
Все Runtime-модули используют один и тот же экземпляр зарегистрированных компонентов.
|
||
|
||
Runtime никогда не создаётся повторно во время обычной работы процесса.
|
||
|
||
---
|
||
|
||
## 7. Composition Outside Runtime
|
||
|
||
Trade Runtime никогда самостоятельно не создаёт собственные зависимости.
|
||
|
||
Все зависимости передаются извне.
|
||
|
||
Composition остаётся единственной точкой создания компонентов.
|
||
|
||
---
|
||
|
||
## 8. Runtime Is Infrastructure
|
||
|
||
Trade Runtime является инфраструктурным уровнем.
|
||
|
||
Runtime не содержит:
|
||
|
||
- транспортной логики;
|
||
- доменной логики;
|
||
- логики получения данных;
|
||
- логики публикации данных.
|
||
|
||
Он обеспечивает исключительно существование Runtime-компонентов.
|
||
|
||
---
|
||
|
||
## 9. Runtime Is Extensible
|
||
|
||
Добавление нового Runtime-модуля не должно требовать изменения архитектуры Runtime.
|
||
|
||
Новый модуль регистрируется внутри существующего Runtime.
|
||
|
||
Создание отдельных Registry для каждого нового модуля запрещается.
|
||
|
||
---
|
||
|
||
## 10. Unique File Naming
|
||
|
||
Во всём проекте Dzentra запрещено существование нескольких файлов с одинаковыми именами независимо от каталогов.
|
||
|
||
Единственным исключением остаётся:
|
||
|
||
```text
|
||
__init__.py
|
||
```
|
||
|
||
Каждый Runtime-компонент получает уникальное имя файла.
|
||
|
||
Например:
|
||
|
||
```text
|
||
trade_runtime_registry.py
|
||
|
||
trade_runtime_protocol.py
|
||
|
||
trade_runtime_exceptions.py
|
||
```
|
||
|
||
---
|
||
|
||
# Модель владения
|
||
|
||
Одной из основных целей Build является разделение различных видов ответственности.
|
||
|
||
До настоящего Build существовало только понятие владельца состояния.
|
||
|
||
Build 060.20 впервые разделяет два независимых уровня владения.
|
||
|
||
---
|
||
|
||
## Владение жизненным циклом
|
||
|
||
За существование Runtime-компонентов отвечает исключительно:
|
||
|
||
```text
|
||
TradeRuntimeRegistry
|
||
```
|
||
|
||
Он определяет:
|
||
|
||
- создание компонентов;
|
||
- регистрацию;
|
||
- хранение;
|
||
- предоставление;
|
||
- повторное использование.
|
||
|
||
Registry никогда не изменяет внутреннее состояние компонентов.
|
||
|
||
---
|
||
|
||
## Владение бизнес-состоянием
|
||
|
||
Каждый Runtime-модуль самостоятельно владеет собственным состоянием.
|
||
|
||
Например:
|
||
|
||
```text
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
остаётся владельцем:
|
||
|
||
- порядка сделок;
|
||
- дедупликации;
|
||
- обнаружения конфликтующих повторов;
|
||
- информации о состоянии Canonical Trade Stream.
|
||
|
||
Registry не имеет доступа к этому состоянию.
|
||
|
||
---
|
||
|
||
## Владение выполнением операций
|
||
|
||
За выполнение бизнес-операций отвечает соответствующий Runtime-модуль.
|
||
|
||
Например:
|
||
|
||
```text
|
||
TradeRecoveryController
|
||
```
|
||
|
||
отвечает исключительно за выполнение Recovery Pipeline.
|
||
|
||
Recovery не отвечает:
|
||
|
||
- за создание Runtime;
|
||
- за регистрацию Runtime;
|
||
- за получение Runtime;
|
||
- за уничтожение Runtime.
|
||
|
||
---
|
||
|
||
# Архитектурная модель Runtime
|
||
|
||
После завершения Build Runtime приобретает следующую структуру.
|
||
|
||
```text
|
||
Trade Runtime
|
||
|
||
│
|
||
|
||
├── Stream Consistency Module
|
||
|
||
│ │
|
||
|
||
│ ▼
|
||
|
||
│ TradeStreamConsistencyController
|
||
|
||
│
|
||
|
||
└── Recovery Module
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeRecoveryController
|
||
```
|
||
|
||
Каждый модуль обладает собственной ответственностью.
|
||
|
||
Ни один модуль не становится владельцем другого.
|
||
|
||
Runtime лишь объединяет их в одну долгоживущую инфраструктурную подсистему.
|
||
|
||
---
|
||
|
||
# TradeRuntimeRegistry
|
||
|
||
TradeRuntimeRegistry является владельцем Runtime Layer.
|
||
|
||
Концептуально Runtime выглядит следующим образом.
|
||
|
||
```text
|
||
TradeRuntimeRegistry
|
||
|
||
│
|
||
|
||
├── Stream Consistency Module
|
||
|
||
│ │
|
||
|
||
│ ▼
|
||
|
||
│ TradeStreamConsistencyController
|
||
|
||
│
|
||
|
||
└── Recovery Module
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeRecoveryController
|
||
```
|
||
|
||
Registry знает,
|
||
|
||
какие Runtime-компоненты существуют.
|
||
|
||
Registry не знает,
|
||
|
||
как работает каждый Runtime-модуль.
|
||
|
||
Это принципиальное архитектурное разделение.
|
||
|
||
---
|
||
|
||
# Инварианты Trade Runtime
|
||
|
||
Любая реализация Runtime обязана удовлетворять следующим архитектурным инвариантам.
|
||
|
||
---
|
||
|
||
## Инвариант №1
|
||
|
||
Trade Runtime существует независимо от любых операций Acquisition.
|
||
|
||
---
|
||
|
||
## Инвариант №2
|
||
|
||
Trade Runtime существует независимо от Recovery.
|
||
|
||
Recovery является пользователем Runtime.
|
||
|
||
---
|
||
|
||
## Инвариант №3
|
||
|
||
TradeRuntimeRegistry является единственным владельцем жизненного цикла Runtime-компонентов.
|
||
|
||
---
|
||
|
||
## Инвариант №4
|
||
|
||
TradeStreamConsistencyController остаётся единственным владельцем состояния Canonical Trade Stream.
|
||
|
||
---
|
||
|
||
## Инвариант №5
|
||
|
||
TradeRecoveryController никогда не владеет состоянием Stream Consistency.
|
||
|
||
---
|
||
|
||
## Инвариант №6
|
||
|
||
Recovery никогда самостоятельно не создаёт Runtime.
|
||
|
||
---
|
||
|
||
## Инвариант №7
|
||
|
||
Feed никогда самостоятельно не создаёт Runtime.
|
||
|
||
---
|
||
|
||
## Инвариант №8
|
||
|
||
Количество Runtime-компонентов не зависит от количества операций.
|
||
|
||
---
|
||
|
||
## Инвариант №9
|
||
|
||
Каждый Runtime-модуль может быть заменён независимо от остальных.
|
||
|
||
---
|
||
|
||
## Инвариант №10
|
||
|
||
Trade Runtime полностью независим от источника данных.
|
||
|
||
REST,
|
||
|
||
WebSocket,
|
||
|
||
Replay,
|
||
|
||
или любой будущий транспорт
|
||
|
||
используют один и тот же Runtime.
|
||
|
||
---
|
||
|
||
# Граница Runtime
|
||
|
||
Build 060.20 вводит новую официальную архитектурную границу.
|
||
|
||
До настоящего Build существовало только Acquisition.
|
||
|
||
```text
|
||
REST
|
||
|
||
↓
|
||
|
||
Recovery
|
||
|
||
↓
|
||
|
||
Consistency
|
||
```
|
||
|
||
После завершения Build появляется самостоятельный Runtime Layer.
|
||
|
||
```text
|
||
Trade Runtime
|
||
|
||
│
|
||
|
||
├── Stream Consistency
|
||
|
||
└── Recovery
|
||
|
||
↓
|
||
|
||
Acquisition Operations
|
||
|
||
↓
|
||
|
||
REST
|
||
|
||
WebSocket
|
||
|
||
Replay
|
||
|
||
...
|
||
```
|
||
|
||
Таким образом Runtime становится постоянной инфраструктурной подсистемой,
|
||
|
||
а Acquisition превращается лишь в набор операций, использующих Runtime.
|
||
|
||
---
|
||
|
||
# Архитектура компонентов
|
||
|
||
После определения модели Trade Runtime необходимо определить архитектурные компоненты, обеспечивающие его существование.
|
||
|
||
Build 060.20 не вводит новую бизнес-логику.
|
||
|
||
Все существующие алгоритмы Recovery и Stream Consistency сохраняются без изменений.
|
||
|
||
Build вводит новую инфраструктурную модель их существования.
|
||
|
||
---
|
||
|
||
# Архитектура Runtime
|
||
|
||
После завершения Build Runtime состоит из трёх независимых компонентов.
|
||
|
||
```text
|
||
Trade Runtime
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeRuntimeRegistry
|
||
|
||
┌─────────┴─────────┐
|
||
|
||
▼ ▼
|
||
|
||
Stream Consistency Module Recovery Module
|
||
|
||
│ │
|
||
|
||
▼ ▼
|
||
|
||
TradeStreamConsistencyController TradeRecoveryController
|
||
```
|
||
|
||
TradeRuntimeRegistry не является владельцем бизнес-логики.
|
||
|
||
Он обеспечивает только существование Runtime-модулей.
|
||
|
||
Каждый Runtime-модуль сохраняет собственную ответственность.
|
||
|
||
---
|
||
|
||
# TradeRuntimeRegistry
|
||
|
||
## Назначение
|
||
|
||
TradeRuntimeRegistry является единственной точкой доступа ко всем Runtime-компонентам Trade Runtime.
|
||
|
||
Registry предоставляет зарегистрированные Runtime-компоненты другим частям системы.
|
||
|
||
Registry не принимает участия в обработке сделок.
|
||
|
||
Registry не выполняет Recovery.
|
||
|
||
Registry не контролирует поток сделок.
|
||
|
||
---
|
||
|
||
# Ответственность Registry
|
||
|
||
Registry отвечает исключительно за:
|
||
|
||
- регистрацию Runtime-компонентов;
|
||
- поиск Runtime-компонентов;
|
||
- предоставление Runtime-компонентов;
|
||
- контроль корректности регистрации;
|
||
- обеспечение повторного использования Runtime-компонентов.
|
||
|
||
---
|
||
|
||
# Registry НЕ отвечает
|
||
|
||
TradeRuntimeRegistry сознательно не отвечает за:
|
||
|
||
- создание бизнес-состояния;
|
||
- выполнение Recovery;
|
||
- получение данных;
|
||
- работу Feed;
|
||
- работу Parser;
|
||
- работу Handler;
|
||
- согласование Trade Stream;
|
||
- транспортную интеграцию;
|
||
- управление жизненным циклом процесса.
|
||
|
||
Registry остаётся исключительно инфраструктурным компонентом Runtime.
|
||
|
||
---
|
||
|
||
# Главный принцип Registry
|
||
|
||
Registry знает,
|
||
|
||
какие Runtime-компоненты существуют.
|
||
|
||
Registry не знает,
|
||
|
||
что делает каждый Runtime-модуль.
|
||
|
||
Именно это позволяет независимо развивать Runtime без изменения Registry.
|
||
|
||
---
|
||
|
||
# Stream Consistency Module
|
||
|
||
## Назначение
|
||
|
||
Stream Consistency Module отвечает за сопровождение непрерывного Canonical Trade Stream.
|
||
|
||
Его центральным компонентом является:
|
||
|
||
```text
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
Build 060.20 не изменяет его алгоритмы.
|
||
|
||
Изменяется исключительно модель его существования.
|
||
|
||
До настоящего Build экземпляр Controller создавался как обычный объект.
|
||
|
||
После завершения Build Controller становится долгоживущим Runtime-компонентом.
|
||
|
||
---
|
||
|
||
# Ответственность Stream Consistency
|
||
|
||
Контроллер продолжает отвечать исключительно за:
|
||
|
||
- контроль порядка сделок;
|
||
- дедупликацию;
|
||
- обнаружение конфликтующих повторов;
|
||
- обнаружение нарушений последовательности;
|
||
- поддержку состояния Canonical Trade Stream.
|
||
|
||
Никаких новых бизнес-обязанностей Build не вводит.
|
||
|
||
---
|
||
|
||
# Почему состояние принадлежит именно этому модулю
|
||
|
||
Во время проектирования рассматривались различные варианты.
|
||
|
||
---
|
||
|
||
## Вариант 1
|
||
|
||
Передать состояние Recovery Module.
|
||
|
||
Отклонён.
|
||
|
||
Recovery выполняет операции.
|
||
|
||
Recovery не сопровождает поток.
|
||
|
||
---
|
||
|
||
## Вариант 2
|
||
|
||
Передать состояние Registry.
|
||
|
||
Отклонён.
|
||
|
||
Registry становится владельцем бизнес-состояния.
|
||
|
||
Это нарушает принцип разделения ответственности.
|
||
|
||
---
|
||
|
||
## Вариант 3
|
||
|
||
Оставить состояние внутри Stream Consistency Module.
|
||
|
||
Принят.
|
||
|
||
Именно данный модуль сопровождает Canonical Trade Stream.
|
||
|
||
Следовательно именно он обязан владеть его состоянием.
|
||
|
||
---
|
||
|
||
# Recovery Module
|
||
|
||
## Назначение
|
||
|
||
Recovery Module отвечает исключительно за выполнение операций восстановления Trade Stream.
|
||
|
||
Его центральным компонентом является:
|
||
|
||
```text
|
||
TradeRecoveryController
|
||
```
|
||
|
||
Recovery Module не является владельцем Runtime.
|
||
|
||
Recovery Module не является владельцем Stream Consistency.
|
||
|
||
Recovery Module является пользователем Runtime.
|
||
|
||
---
|
||
|
||
# Ответственность Recovery Module
|
||
|
||
Recovery Module отвечает исключительно за:
|
||
|
||
- выполнение Recovery Pipeline;
|
||
- получение Recovery Source;
|
||
- передачу сделок в Stream Consistency;
|
||
- возврат результата Recovery.
|
||
|
||
---
|
||
|
||
# Recovery Module НЕ отвечает
|
||
|
||
Recovery Module сознательно не отвечает за:
|
||
|
||
- создание Runtime;
|
||
- регистрацию Runtime;
|
||
- создание Stream Consistency;
|
||
- управление жизненным циклом Runtime;
|
||
- хранение состояния Canonical Trade Stream.
|
||
|
||
Все перечисленные обязанности принадлежат другим компонентам Runtime.
|
||
|
||
---
|
||
|
||
# Главный принцип Recovery Module
|
||
|
||
Recovery выполняет операции.
|
||
|
||
Stream Consistency сопровождает поток.
|
||
|
||
Registry обеспечивает существование компонентов.
|
||
|
||
Каждый Runtime-модуль отвечает только за собственную область ответственности.
|
||
|
||
---
|
||
|
||
# Взаимодействие Runtime-модулей
|
||
|
||
Runtime-модули взаимодействуют исключительно через публичные контракты.
|
||
|
||
Концептуально схема выглядит следующим образом.
|
||
|
||
```text
|
||
Trade Runtime
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeRuntimeRegistry
|
||
|
||
┌─────────┴─────────┐
|
||
|
||
▼ ▼
|
||
|
||
TradeStreamConsistencyController TradeRecoveryController
|
||
|
||
▲ │
|
||
|
||
└───────────────────┘
|
||
|
||
Recovery использует
|
||
|
||
Stream Consistency
|
||
```
|
||
|
||
Из данной схемы следует:
|
||
|
||
- Registry ничего не знает о внутреннем устройстве Recovery;
|
||
- Registry ничего не знает о внутреннем устройстве Stream Consistency;
|
||
- Recovery знает только публичный контракт Stream Consistency;
|
||
- Stream Consistency ничего не знает о Recovery.
|
||
|
||
Таким образом Runtime состоит из независимых модулей с минимально необходимыми зависимостями.
|
||
|
||
---
|
||
|
||
# Главная архитектурная граница
|
||
|
||
После завершения Build официальная архитектурная модель становится следующей.
|
||
|
||
```text
|
||
Runtime Layer
|
||
|
||
TradeRuntimeRegistry
|
||
|
||
│
|
||
|
||
┌──────────┴──────────┐
|
||
|
||
▼ ▼
|
||
|
||
Stream Consistency Recovery Module
|
||
|
||
────────────────────────────────────────────
|
||
|
||
Acquisition Layer
|
||
|
||
────────────────────────────────────────────
|
||
|
||
REST
|
||
|
||
WebSocket
|
||
|
||
Replay
|
||
|
||
Recovery Requests
|
||
|
||
...
|
||
|
||
────────────────────────────────────────────
|
||
|
||
Domain Layer
|
||
|
||
────────────────────────────────────────────
|
||
|
||
Canonical Trade Stream
|
||
```
|
||
|
||
Trade Runtime становится самостоятельным инфраструктурным слоем системы.
|
||
|
||
Acquisition использует Runtime.
|
||
|
||
Domain получает уже согласованный поток сделок.
|
||
|
||
Ни один слой не нарушает ответственность другого.
|
||
|
||
---
|
||
|
||
# Архитектура Runtime Pipeline
|
||
|
||
## Основной принцип
|
||
|
||
Build 060.20 не изменяет существующий Pipeline получения сделок.
|
||
|
||
Изменяется исключительно способ получения Runtime-компонентов.
|
||
|
||
До настоящего Build Runtime-компоненты создавались непосредственно внутри Recovery.
|
||
|
||
После завершения Build Recovery использует уже существующий Trade Runtime.
|
||
|
||
Таким образом Runtime становится независимой инфраструктурной подсистемой, существующей до начала любой операции Acquisition.
|
||
|
||
---
|
||
|
||
# Recovery Pipeline
|
||
|
||
После завершения Build выполнение Recovery выглядит следующим образом.
|
||
|
||
```text
|
||
Composition Root
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeRuntimeRegistry
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeRecoveryController
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeDocumentSource
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeDocumentHandler
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
Trade
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeStreamConsistencyController
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
Canonical Trade Stream
|
||
```
|
||
|
||
Runtime существует независимо от данного Pipeline.
|
||
|
||
Pipeline использует Runtime,
|
||
|
||
но не определяет его жизненный цикл.
|
||
|
||
---
|
||
|
||
# Integration Boundary
|
||
|
||
Build 060.20 вводит официальную границу интеграции Runtime.
|
||
|
||
До настоящего Build существовала следующая схема.
|
||
|
||
```text
|
||
Recovery
|
||
|
||
↓
|
||
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
После завершения Build архитектура становится следующей.
|
||
|
||
```text
|
||
Recovery Module
|
||
|
||
↓
|
||
|
||
Trade Runtime
|
||
|
||
↓
|
||
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
Recovery больше не знает:
|
||
|
||
- где создаётся Controller;
|
||
- сколько экземпляров существует;
|
||
- каким образом обеспечивается повторное использование.
|
||
|
||
Recovery использует исключительно публичный контракт Runtime.
|
||
|
||
---
|
||
|
||
# Dependency Injection
|
||
|
||
Ни один Runtime-модуль не создаёт собственные зависимости.
|
||
|
||
Все Runtime-компоненты создаются вне Runtime.
|
||
|
||
Концептуально архитектура выглядит следующим образом.
|
||
|
||
```text
|
||
Composition Root
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeRuntimeRegistry
|
||
|
||
│
|
||
|
||
├──────────────┐
|
||
|
||
▼ ▼
|
||
|
||
TradeRecoveryController
|
||
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
Таким образом:
|
||
|
||
- Composition знает способ создания компонентов;
|
||
- Registry знает способ предоставления компонентов;
|
||
- Runtime-модули знают только собственные публичные зависимости.
|
||
|
||
---
|
||
|
||
# Последовательность выполнения Recovery
|
||
|
||
После определения архитектуры Runtime необходимо определить официальный алгоритм выполнения Recovery.
|
||
|
||
Recovery рассматривается как последовательность операций над уже существующим Runtime.
|
||
|
||
---
|
||
|
||
## Шаг 1
|
||
|
||
Получение Runtime-компонентов.
|
||
|
||
```text
|
||
TradeRuntimeRegistry
|
||
|
||
↓
|
||
|
||
TradeRecoveryController
|
||
|
||
↓
|
||
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
Recovery получает уже зарегистрированные Runtime-компоненты.
|
||
|
||
Если Runtime отсутствует,
|
||
|
||
Recovery не начинается.
|
||
|
||
Создание Runtime не относится к ответственности Recovery.
|
||
|
||
---
|
||
|
||
## Шаг 2
|
||
|
||
Получение транспортных документов.
|
||
|
||
```text
|
||
TradeDocumentSource
|
||
|
||
↓
|
||
|
||
TradeDocumentHandler
|
||
```
|
||
|
||
Все транспортные документы преобразуются в каноническую модель:
|
||
|
||
```text
|
||
Trade
|
||
```
|
||
|
||
---
|
||
|
||
## Шаг 3
|
||
|
||
Передача сделок в Stream Consistency.
|
||
|
||
Каждая полученная сделка передаётся существующему экземпляру:
|
||
|
||
```text
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
Именно этот Runtime-модуль принимает решение:
|
||
|
||
- принять сделку;
|
||
- отбросить повтор;
|
||
- определить нарушение порядка;
|
||
- зафиксировать Gap.
|
||
|
||
---
|
||
|
||
## Шаг 4
|
||
|
||
Обновление состояния Runtime.
|
||
|
||
После успешной обработки внутреннее состояние Runtime обновляется.
|
||
|
||
Изменение состояния производится исключительно средствами:
|
||
|
||
```text
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
TradeRuntimeRegistry участия в изменении состояния не принимает.
|
||
|
||
Recovery также не изменяет состояние напрямую.
|
||
|
||
---
|
||
|
||
## Шаг 5
|
||
|
||
Возврат результата.
|
||
|
||
После завершения обработки Recovery возвращает результат вызывающей стороне.
|
||
|
||
Trade Runtime продолжает существовать.
|
||
|
||
Никакие Runtime-компоненты после завершения Recovery не уничтожаются.
|
||
|
||
---
|
||
|
||
# Почему Runtime существует раньше Recovery
|
||
|
||
Во время проектирования рассматривалась альтернативная архитектура.
|
||
|
||
```text
|
||
Recovery
|
||
|
||
↓
|
||
|
||
Создать Runtime
|
||
|
||
↓
|
||
|
||
Выполнить Recovery
|
||
```
|
||
|
||
Данная модель была отклонена.
|
||
|
||
Причины:
|
||
|
||
- Recovery начинает управлять Runtime;
|
||
- Runtime становится зависимым от Recovery;
|
||
- невозможно совместное использование Runtime другими модулями;
|
||
- WebSocket впоследствии потребует собственный Runtime;
|
||
- появляются различные механизмы создания Runtime.
|
||
|
||
Такая архитектура нарушает принцип единственного владельца жизненного цикла.
|
||
|
||
---
|
||
|
||
# Официальная последовательность
|
||
|
||
Build закрепляет следующий порядок выполнения.
|
||
|
||
```text
|
||
Получить Runtime
|
||
|
||
↓
|
||
|
||
Получить документы
|
||
|
||
↓
|
||
|
||
Преобразовать документы
|
||
|
||
↓
|
||
|
||
Передать сделки в Stream Consistency
|
||
|
||
↓
|
||
|
||
Обновить Runtime State
|
||
|
||
↓
|
||
|
||
Вернуть результат
|
||
```
|
||
|
||
Изменение данной последовательности запрещается.
|
||
|
||
---
|
||
|
||
# Атомарность Runtime
|
||
|
||
Любая ошибка Recovery не должна нарушать внутреннюю согласованность Runtime.
|
||
|
||
Если Recovery завершается ошибкой,
|
||
|
||
Trade Runtime обязан оставаться в корректном состоянии.
|
||
|
||
Это означает:
|
||
|
||
- Registry продолжает существовать;
|
||
- Runtime-модули продолжают существовать;
|
||
- внутреннее состояние изменяется только успешно обработанными сделками;
|
||
- незавершённая Recovery не разрушает Runtime.
|
||
|
||
---
|
||
|
||
# Архитектурная диаграмма
|
||
|
||
Полная архитектура подсистемы после завершения Build выглядит следующим образом.
|
||
|
||
```text
|
||
────────────────────────────────────────────────────────
|
||
|
||
Trade Runtime Layer
|
||
|
||
────────────────────────────────────────────────────────
|
||
|
||
TradeRuntimeRegistry
|
||
|
||
│
|
||
|
||
┌───────────────┴───────────────┐
|
||
|
||
▼ ▼
|
||
|
||
TradeStreamConsistencyController TradeRecoveryController
|
||
|
||
────────────────────────────────────────────────────────
|
||
|
||
Acquisition Layer
|
||
|
||
────────────────────────────────────────────────────────
|
||
|
||
TradeDocumentSource
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
TradeDocumentHandler
|
||
|
||
│
|
||
|
||
▼
|
||
|
||
Trade
|
||
|
||
────────────────────────────────────────────────────────
|
||
|
||
Domain Layer
|
||
|
||
────────────────────────────────────────────────────────
|
||
|
||
Canonical Trade Stream
|
||
```
|
||
|
||
Trade Runtime становится постоянной инфраструктурной подсистемой.
|
||
|
||
Acquisition получает доступ к Runtime исключительно через Registry.
|
||
|
||
---
|
||
|
||
# Интеграция с Acquisition
|
||
|
||
Build 060.20 не изменяет существующий Acquisition Pipeline.
|
||
|
||
Он изменяет только модель владения Runtime.
|
||
|
||
До настоящего Build существовала следующая схема.
|
||
|
||
```text
|
||
Recovery
|
||
|
||
↓
|
||
|
||
Consistency
|
||
```
|
||
|
||
После завершения Build.
|
||
|
||
```text
|
||
Trade Runtime
|
||
|
||
│
|
||
|
||
├── Stream Consistency
|
||
|
||
└── Recovery
|
||
|
||
↓
|
||
|
||
Acquisition
|
||
```
|
||
|
||
Никакой существующий алгоритм обработки сделок не изменяется.
|
||
|
||
Изменяется исключительно модель существования Runtime-компонентов.
|
||
|
||
---
|
||
|
||
# Расширяемость Runtime
|
||
|
||
Одной из целей новой архитектуры является возможность постепенного расширения Runtime без изменения уже существующей структуры.
|
||
|
||
Например:
|
||
|
||
```text
|
||
Trade Runtime
|
||
|
||
│
|
||
|
||
├── Stream Consistency Module
|
||
|
||
├── Recovery Module
|
||
|
||
├── Gap Detection Module
|
||
|
||
├── Replay Module
|
||
|
||
├── Stream Monitoring Module
|
||
|
||
└── Runtime Scheduler Module
|
||
```
|
||
|
||
Добавление нового Runtime-модуля не требует:
|
||
|
||
- создания нового Registry;
|
||
- изменения существующих Runtime-модулей;
|
||
- изменения Acquisition Pipeline.
|
||
|
||
Достаточно зарегистрировать новый Runtime-компонент в существующем `TradeRuntimeRegistry`.
|
||
|
||
Именно эта модель рассматривается как целевая архитектура дальнейшего развития Runtime Layer.
|
||
|
||
---
|
||
|
||
# План изменений файлов
|
||
|
||
Build 060.20 вводит первую инфраструктурную подсистему Trade Runtime.
|
||
|
||
Предлагаемая структура.
|
||
|
||
```text
|
||
market_data/acquisition/
|
||
|
||
└── runtime/
|
||
|
||
└── trade/
|
||
|
||
├── __init__.py
|
||
|
||
├── trade_runtime_registry.py
|
||
|
||
├── trade_runtime_protocol.py
|
||
|
||
├── trade_runtime_exceptions.py
|
||
```
|
||
|
||
Build не изменяет структуру существующих компонентов Acquisition.
|
||
|
||
Trade Runtime добавляется как самостоятельный инфраструктурный слой.
|
||
|
||
---
|
||
|
||
# trade_runtime_registry.py
|
||
|
||
Содержит:
|
||
|
||
```text
|
||
TradeRuntimeRegistry
|
||
```
|
||
|
||
Отвечает исключительно за:
|
||
|
||
- регистрацию Runtime-компонентов;
|
||
- получение Runtime-компонентов;
|
||
- повторное использование Runtime-компонентов.
|
||
|
||
Registry не содержит бизнес-логики.
|
||
|
||
---
|
||
|
||
# trade_runtime_protocol.py
|
||
|
||
Содержит публичный контракт Runtime.
|
||
|
||
Все внешние компоненты должны зависеть исключительно от Protocol.
|
||
|
||
Конкретная реализация Registry остаётся внутренней деталью Runtime.
|
||
|
||
---
|
||
|
||
# trade_runtime_exceptions.py
|
||
|
||
Содержит инфраструктурные исключения Runtime.
|
||
|
||
Например:
|
||
|
||
- RuntimeNotRegisteredError;
|
||
- RuntimeAlreadyRegisteredError;
|
||
- InvalidRuntimeComponentError.
|
||
|
||
Build не вводит новые исключения Recovery Pipeline.
|
||
|
||
Исключения относятся исключительно к инфраструктуре Runtime.
|
||
|
||
---
|
||
|
||
# Изменяемые файлы
|
||
|
||
Build должен минимально затронуть существующий код.
|
||
|
||
Изменения предполагаются только в следующих точках интеграции.
|
||
|
||
- Composition Root;
|
||
- временная точка композиции (`service.py`);
|
||
- Recovery Pipeline.
|
||
|
||
Все остальные изменения должны быть локализованы внутри новой подсистемы Trade Runtime.
|
||
|
||
---
|
||
|
||
# Architectural Decision Records
|
||
|
||
## ADR-060.20-01 — Trade Runtime
|
||
|
||
### Решение
|
||
|
||
Trade Runtime является самостоятельной инфраструктурной подсистемой.
|
||
|
||
Runtime существует независимо от любых Acquisition-операций.
|
||
|
||
Recovery является одним из Runtime-модулей.
|
||
|
||
---
|
||
|
||
## ADR-060.20-02 — Runtime Lifecycle Ownership
|
||
|
||
### Решение
|
||
|
||
Жизненным циклом Runtime-компонентов владеет исключительно:
|
||
|
||
```text
|
||
TradeRuntimeRegistry
|
||
```
|
||
|
||
Никакой другой компонент системы не имеет права создавать альтернативные экземпляры Runtime.
|
||
|
||
---
|
||
|
||
## ADR-060.20-03 — Business State Ownership
|
||
|
||
### Решение
|
||
|
||
Жизненный цикл компонентов и бизнес-состояние разделены.
|
||
|
||
TradeRuntimeRegistry владеет существованием Runtime-компонентов.
|
||
|
||
TradeStreamConsistencyController остаётся единственным владельцем состояния Canonical Trade Stream.
|
||
|
||
---
|
||
|
||
## ADR-060.20-04 — Recovery Independence
|
||
|
||
### Решение
|
||
|
||
TradeRecoveryController никогда самостоятельно не создаёт Runtime.
|
||
|
||
Recovery получает Runtime исключительно через публичный контракт Registry.
|
||
|
||
---
|
||
|
||
## ADR-060.20-05 — Runtime Boundary
|
||
|
||
### Решение
|
||
|
||
Trade Runtime становится официальной инфраструктурной границей между Runtime Layer и Acquisition Layer.
|
||
|
||
Все последующие Build обязаны использовать данную модель.
|
||
|
||
---
|
||
|
||
## ADR-060.20-06 — Registry Responsibility
|
||
|
||
### Решение
|
||
|
||
TradeRuntimeRegistry является исключительно инфраструктурным каталогом Runtime-компонентов.
|
||
|
||
Registry:
|
||
|
||
- не содержит бизнес-логики;
|
||
- не выполняет Recovery;
|
||
- не управляет состоянием Canonical Trade Stream;
|
||
- не знает внутреннего устройства Runtime-модулей.
|
||
|
||
---
|
||
|
||
## ADR-060.20-07 — Runtime Extensibility
|
||
|
||
### Решение
|
||
|
||
Trade Runtime должен расширяться посредством регистрации новых Runtime-модулей.
|
||
|
||
Создание отдельных специализированных Registry запрещается.
|
||
|
||
Все Runtime-компоненты регистрируются внутри единого:
|
||
|
||
```text
|
||
TradeRuntimeRegistry
|
||
```
|
||
|
||
---
|
||
|
||
# Стратегия тестирования
|
||
|
||
Build 060.20 вводит первую инфраструктурную подсистему Runtime.
|
||
|
||
Поэтому объектом тестирования становится не только Registry как класс.
|
||
|
||
Необходимо подтвердить корректность всей архитектурной модели Runtime.
|
||
|
||
---
|
||
|
||
# Основные принципы тестирования
|
||
|
||
## Проверяются архитектурные инварианты
|
||
|
||
Главным объектом тестирования являются инварианты Trade Runtime.
|
||
|
||
Проверяется не реализация конкретного метода,
|
||
|
||
а соблюдение архитектурных правил.
|
||
|
||
---
|
||
|
||
## Проверяются публичные контракты
|
||
|
||
Тесты взаимодействуют исключительно через публичный Runtime Protocol.
|
||
|
||
Внутренняя реализация Registry не должна влиять на тесты.
|
||
|
||
---
|
||
|
||
## Один тест — один инвариант
|
||
|
||
Каждый негативный сценарий проверяет нарушение только одного архитектурного правила.
|
||
|
||
Это обеспечивает понятную диагностику ошибок.
|
||
|
||
---
|
||
|
||
## Детерминированность
|
||
|
||
Все тесты должны быть полностью воспроизводимыми.
|
||
|
||
Никакие случайные значения,
|
||
|
||
внешние сервисы,
|
||
|
||
или сетевые события
|
||
|
||
не должны влиять на результат.
|
||
|
||
---
|
||
|
||
# Уровни тестирования
|
||
|
||
Build вводит три уровня проверки.
|
||
|
||
---
|
||
|
||
## Unit Tests
|
||
|
||
Изолированно проверяются:
|
||
|
||
- TradeRuntimeRegistry;
|
||
- Runtime Protocol.
|
||
|
||
Все зависимости заменяются тестовыми объектами.
|
||
|
||
---
|
||
|
||
## Integration Tests
|
||
|
||
Проверяется полный путь получения Runtime.
|
||
|
||
```text
|
||
Composition Root
|
||
|
||
↓
|
||
|
||
TradeRuntimeRegistry
|
||
|
||
↓
|
||
|
||
TradeRecoveryController
|
||
|
||
↓
|
||
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
Основная задача —
|
||
|
||
доказать,
|
||
|
||
что Runtime корректно интегрирован в существующую архитектуру.
|
||
|
||
---
|
||
|
||
## Regression Tests
|
||
|
||
Подтверждается,
|
||
|
||
что Build 060.20
|
||
|
||
не изменил поведение предыдущих Build.
|
||
|
||
В частности:
|
||
|
||
- Feed;
|
||
- Handler;
|
||
- Stream Consistency;
|
||
- Recovery Pipeline.
|
||
|
||
---
|
||
|
||
# Матрица тестирования
|
||
|
||
## 1. Регистрация Runtime-компонента
|
||
|
||
Проверяется успешная регистрация Runtime-модуля.
|
||
|
||
Ожидаемый результат:
|
||
|
||
зарегистрированный компонент становится доступным через Registry.
|
||
|
||
---
|
||
|
||
## 2. Повторное получение Runtime
|
||
|
||
Проверяется повторный запрос зарегистрированного компонента.
|
||
|
||
Ожидаемый результат:
|
||
|
||
возвращается тот же экземпляр.
|
||
|
||
---
|
||
|
||
## 3. Несколько Runtime-модулей
|
||
|
||
Проверяется регистрация нескольких независимых Runtime-компонентов.
|
||
|
||
Ожидаемый результат:
|
||
|
||
каждый Runtime-модуль доступен независимо.
|
||
|
||
---
|
||
|
||
## 4. Повторное использование Runtime
|
||
|
||
Несколько Recovery используют один и тот же Runtime.
|
||
|
||
Ожидаемый результат:
|
||
|
||
новые экземпляры не создаются.
|
||
|
||
---
|
||
|
||
## 5. Сохранение состояния
|
||
|
||
Несколько последовательных Recovery.
|
||
|
||
Ожидаемый результат:
|
||
|
||
TradeStreamConsistencyController сохраняет своё состояние.
|
||
|
||
---
|
||
|
||
## 6. Ошибка отсутствующего Runtime
|
||
|
||
Попытка получения незарегистрированного Runtime.
|
||
|
||
Ожидаемый результат:
|
||
|
||
генерируется инфраструктурное исключение Runtime.
|
||
|
||
---
|
||
|
||
## 7. Независимость Recovery
|
||
|
||
Recovery не создаёт Runtime самостоятельно.
|
||
|
||
Ожидаемый результат:
|
||
|
||
используются только зарегистрированные Runtime-компоненты.
|
||
|
||
---
|
||
|
||
## 8. Совместимость
|
||
|
||
Проверяется существующий Acquisition Pipeline.
|
||
|
||
Ожидаемый результат:
|
||
|
||
поведение системы не изменилось.
|
||
|
||
---
|
||
|
||
# Матрица архитектурных инвариантов
|
||
|
||
| Инвариант | Проверка |
|
||
|-----------|----------|
|
||
| Runtime Lifetime | Unit |
|
||
| Runtime Ownership | Unit |
|
||
| Business State Ownership | Unit |
|
||
| Registry Responsibility | Unit |
|
||
| Runtime Boundary | Integration |
|
||
| Runtime Reuse | Integration |
|
||
| Stateless Acquisition | Regression |
|
||
| Recovery Independence | Regression |
|
||
| Existing Feed Behaviour | Regression |
|
||
|
||
---
|
||
|
||
# Definition of Done
|
||
|
||
Build считается завершённым только после выполнения всех перечисленных условий.
|
||
|
||
---
|
||
|
||
## Архитектура
|
||
|
||
- Все ADR реализованы без отклонений.
|
||
- Runtime Layer полностью соответствует настоящей спецификации.
|
||
- Registry остаётся инфраструктурным компонентом.
|
||
- Runtime отделён от Acquisition.
|
||
- Runtime допускает дальнейшее расширение новыми модулями.
|
||
|
||
---
|
||
|
||
## Код
|
||
|
||
- Не изменена бизнес-логика Recovery.
|
||
- Не изменена бизнес-логика Stream Consistency.
|
||
- Не изменён Acquisition Pipeline.
|
||
- Не нарушены существующие публичные API.
|
||
|
||
---
|
||
|
||
## Функциональность
|
||
|
||
Поддерживаются:
|
||
|
||
- единый Trade Runtime;
|
||
- единый экземпляр Runtime-компонентов;
|
||
- повторное использование Runtime;
|
||
- сохранение состояния между Recovery;
|
||
- независимость Runtime от Acquisition;
|
||
- готовность к регистрации новых Runtime-модулей.
|
||
|
||
---
|
||
|
||
## Тестирование
|
||
|
||
Все Unit Tests проходят.
|
||
|
||
Все Integration Tests проходят.
|
||
|
||
Все Regression Tests проходят без изменений.
|
||
|
||
---
|
||
|
||
## Документация
|
||
|
||
Обновлены:
|
||
|
||
- Architecture Specification;
|
||
- ADR;
|
||
- Architecture Diagram;
|
||
- File Plan.
|
||
|
||
---
|
||
|
||
# План реализации
|
||
|
||
Настоящий Build должен реализовываться строго поэтапно.
|
||
|
||
Переход к следующему этапу допускается только после полного завершения предыдущего.
|
||
|
||
---
|
||
|
||
## Этап 1 — Создание Runtime Layer
|
||
|
||
Создаётся новая инфраструктурная подсистема:
|
||
|
||
```text
|
||
market_data/acquisition/
|
||
└── runtime/
|
||
└── trade/
|
||
```
|
||
|
||
Добавляются:
|
||
|
||
- `trade_runtime_registry.py`;
|
||
- `trade_runtime_protocol.py`;
|
||
- `trade_runtime_exceptions.py`.
|
||
|
||
На данном этапе существующая бизнес-логика системы не изменяется.
|
||
|
||
---
|
||
|
||
## Этап 2 — Реализация TradeRuntimeRegistry
|
||
|
||
Реализуется инфраструктурный компонент:
|
||
|
||
```text
|
||
TradeRuntimeRegistry
|
||
```
|
||
|
||
Registry должен обеспечивать:
|
||
|
||
- регистрацию Runtime-компонентов;
|
||
- получение Runtime-компонентов;
|
||
- повторное использование зарегистрированных экземпляров;
|
||
- инфраструктурные проверки корректности регистрации.
|
||
|
||
Никакие бизнес-алгоритмы на данном этапе не изменяются.
|
||
|
||
---
|
||
|
||
## Этап 3 — Интеграция Stream Consistency
|
||
|
||
Существующий:
|
||
|
||
```text
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
становится Runtime-компонентом.
|
||
|
||
Изменяется только способ его получения.
|
||
|
||
Алгоритмы:
|
||
|
||
- дедупликации;
|
||
- проверки последовательности;
|
||
- сопровождения Canonical Trade Stream
|
||
|
||
остаются полностью неизменными.
|
||
|
||
---
|
||
|
||
## Этап 4 — Интеграция Recovery
|
||
|
||
Существующий:
|
||
|
||
```text
|
||
TradeRecoveryController
|
||
```
|
||
|
||
переводится на использование Runtime.
|
||
|
||
Recovery получает Runtime-компоненты исключительно через публичный Runtime Protocol.
|
||
|
||
Создание Runtime внутри Recovery полностью исключается.
|
||
|
||
---
|
||
|
||
## Этап 5 — Интеграция Composition Root
|
||
|
||
Текущая временная композиция (`service.py`) обновляется таким образом, чтобы:
|
||
|
||
- создать Runtime-компоненты;
|
||
- зарегистрировать их в `TradeRuntimeRegistry`;
|
||
- передать Registry остальным компонентам системы.
|
||
|
||
В дальнейшем данная логика будет перенесена в постоянный Composition Root.
|
||
|
||
---
|
||
|
||
## Этап 6 — Архитектурная проверка
|
||
|
||
После завершения интеграции необходимо подтвердить выполнение всех архитектурных инвариантов Build.
|
||
|
||
Проверяется:
|
||
|
||
- независимость Runtime;
|
||
- единственность Runtime-компонентов;
|
||
- отсутствие изменений бизнес-логики;
|
||
- корректность повторного использования Runtime;
|
||
- отсутствие прямого создания Runtime внутри Recovery.
|
||
|
||
---
|
||
|
||
# Build Boundary
|
||
|
||
Настоящий Build имеет строго ограниченную область ответственности.
|
||
|
||
---
|
||
|
||
## Build отвечает за
|
||
|
||
- построение архитектуры Trade Runtime;
|
||
- введение Runtime Layer;
|
||
- введение TradeRuntimeRegistry;
|
||
- определение Runtime Protocol;
|
||
- разделение жизненного цикла и бизнес-состояния;
|
||
- определение архитектурных инвариантов;
|
||
- подготовку Runtime к дальнейшему расширению.
|
||
|
||
---
|
||
|
||
## Build сознательно НЕ отвечает за
|
||
|
||
- изменение алгоритмов Recovery;
|
||
- изменение алгоритмов Stream Consistency;
|
||
- реализацию WebSocket Feed;
|
||
- реализацию Gap Detection;
|
||
- реализацию Runtime Scheduler;
|
||
- реализацию Monitoring;
|
||
- реализацию Runtime Metrics;
|
||
- реализацию Runtime Health Check;
|
||
- реализацию Runtime Persistence;
|
||
- построение окончательного Composition Root.
|
||
|
||
Все перечисленные задачи относятся к последующим Build серии 060.
|
||
|
||
---
|
||
|
||
# Архитектурный результат
|
||
|
||
После завершения Build система впервые получает полноценную архитектуру Trade Runtime как самостоятельного инфраструктурного слоя.
|
||
|
||
До Build 060.20:
|
||
|
||
```text
|
||
Recovery
|
||
|
||
↓
|
||
|
||
TradeStreamConsistencyController
|
||
```
|
||
|
||
После Build 060.20:
|
||
|
||
```text
|
||
Trade Runtime
|
||
|
||
│
|
||
|
||
┌───────────────┴───────────────┐
|
||
|
||
▼ ▼
|
||
|
||
TradeRuntimeRegistry
|
||
|
||
│
|
||
|
||
├──────────────────────────┐
|
||
|
||
▼ ▼
|
||
|
||
TradeStreamConsistencyController
|
||
|
||
TradeRecoveryController
|
||
|
||
────────────────────────────────────────
|
||
|
||
Acquisition
|
||
|
||
────────────────────────────────────────
|
||
|
||
REST
|
||
|
||
WebSocket
|
||
|
||
Replay
|
||
|
||
Future Sources
|
||
|
||
────────────────────────────────────────
|
||
|
||
Canonical Trade Stream
|
||
```
|
||
|
||
Trade Runtime становится самостоятельным инфраструктурным слоем системы.
|
||
|
||
Recovery становится Runtime-модулем.
|
||
|
||
Stream Consistency становится Runtime-модулем.
|
||
|
||
Registry становится единственным владельцем жизненного цикла Runtime-компонентов.
|
||
|
||
---
|
||
|
||
# Архитектурные последствия
|
||
|
||
После завершения Build становятся возможны последующие этапы развития без изменения базовой архитектуры.
|
||
|
||
Например:
|
||
|
||
```text
|
||
Trade Runtime
|
||
|
||
│
|
||
|
||
├── Infrastructure
|
||
│ └── TradeRuntimeRegistry
|
||
|
||
├── Stream Consistency Module
|
||
│ └── TradeStreamConsistencyController
|
||
|
||
├── Recovery Module
|
||
│ └── TradeRecoveryController
|
||
|
||
├── Gap Detection Module
|
||
|
||
├── Stream Monitoring Module
|
||
|
||
├── Replay Module
|
||
|
||
├── Runtime Scheduler Module
|
||
|
||
├── Runtime Metrics Module
|
||
|
||
└── ...
|
||
```
|
||
|
||
Добавление нового Runtime-модуля требует только:
|
||
|
||
1. создания нового компонента;
|
||
2. регистрации его в `TradeRuntimeRegistry`;
|
||
3. использования публичного Runtime Protocol.
|
||
|
||
Существующая архитектура при этом не изменяется.
|
||
|
||
---
|
||
|
||
# Заключение
|
||
|
||
Build 060.20 впервые формализует Trade Runtime как самостоятельную архитектурную подсистему Dzentra.
|
||
|
||
TradeRuntimeRegistry является инфраструктурным ядром этой подсистемы, но не исчерпывает её. Runtime включает также Runtime-модули, архитектурные инварианты, модель владения и правила расширения, определённые настоящей спецификацией.
|
||
|
||
В результате выполнения Build достигаются следующие цели:
|
||
|
||
- Runtime становится самостоятельной инфраструктурной подсистемой;
|
||
- жизненный цикл Runtime-компонентов отделяется от бизнес-состояния;
|
||
- Recovery перестаёт быть владельцем Runtime;
|
||
- Stream Consistency сохраняет полное владение состоянием Canonical Trade Stream;
|
||
- все Runtime-компоненты получают единый механизм регистрации и повторного использования;
|
||
- Runtime становится независимым от конкретного транспорта получения данных.
|
||
|
||
Данная архитектура является базовой для всех последующих Build серии 060 и определяет единый подход к построению долгоживущих Runtime-подсистем Dzentra.
|
||
|
||
Любые последующие расширения Runtime должны соответствовать архитектурным принципам, инвариантам и ADR, закреплённым настоящей спецификацией.
|