Build 060.20_1: align Trade Stream state ownership

This commit is contained in:
2026-07-25 10:41:01 +03:00
parent 14f698d48a
commit ad6631f773
14 changed files with 4311 additions and 431 deletions

View File

@@ -8,10 +8,10 @@ from src.market_data.acquisition.consistency.trade_stream_protocol import (
from src.market_data.acquisition.consistency.trade_stream_state import (
TradeStreamState,
)
from src.market_data.acquisition.models.trade import Trade
from src.market_data.acquisition.runtime.trade.trade_runtime_protocol import (
TradeRuntimeProtocol,
from src.market_data.acquisition.consistency.trade_stream_state_store_protocol import (
TradeStreamStateStoreProtocol,
)
from src.market_data.acquisition.models.trade import Trade
class TradeStreamConsistencyController(
@@ -20,18 +20,16 @@ class TradeStreamConsistencyController(
"""
Контроллер проверки согласованности Canonical Trade Stream.
Для каждого торгового инструмента поддерживается
независимое состояние проверки, которое хранится
в Trade Runtime Registry.
Для каждого торгового инструмента используется
специализированное хранилище состояний
Trade Stream Consistency.
"""
_RUNTIME_NAMESPACE = "consistency"
def __init__(
self,
runtime: TradeRuntimeProtocol,
state_store: TradeStreamStateStoreProtocol,
) -> None:
self._runtime = runtime
self._state_store = state_store
def accept(
self,
@@ -45,24 +43,11 @@ class TradeStreamConsistencyController(
self,
symbol: str,
) -> TradeStreamState:
key = self._runtime_key(symbol)
if self._runtime.is_registered(key):
return self._runtime.get(key)
state = TradeStreamState(symbol=symbol)
self._runtime.register(key, state)
return state
@classmethod
def _runtime_key(
cls,
symbol: str,
) -> str:
"""
Возвращает ключ Runtime Registry
для состояния проверки Trade Stream.
"""
Возвращает состояние проверки Trade Stream
для указанного торгового инструмента.
return f"{cls._RUNTIME_NAMESPACE}:{symbol}"
При первом обращении состояние автоматически
создаётся специализированным хранилищем.
"""
return self._state_store.get_or_create(symbol)

View File

@@ -0,0 +1,129 @@
# app/src/market_data/acquisition/consistency/trade_stream_state_store.py
from __future__ import annotations
"""
Хранилище состояний Trade Stream Consistency.
Build 060.20.1 переносит владение инфраструктурным состоянием
из общего Runtime Registry в специализированное хранилище
подсистемы проверки согласованности потока сделок.
Хранилище отвечает исключительно за жизненный цикл объектов
TradeStreamState и не содержит логики проверки последовательности
или восстановления потока сделок.
"""
from src.market_data.acquisition.consistency.trade_stream_state import (
TradeStreamState,
)
from src.market_data.acquisition.consistency.trade_stream_state_store_exceptions import (
TradeStreamStateNotFoundError,
)
from src.market_data.acquisition.consistency.trade_stream_state_store_protocol import (
TradeStreamStateStoreProtocol,
)
class TradeStreamStateStore(TradeStreamStateStoreProtocol):
"""
Хранилище состояний Trade Stream.
Для каждого торгового инструмента существует
единственный экземпляр TradeStreamState.
"""
def __init__(self) -> None:
"""
Создаёт пустое хранилище состояний.
"""
self._states: dict[str, TradeStreamState] = {}
def get_or_create(
self,
symbol: str,
) -> TradeStreamState:
"""
Возвращает существующее состояние либо создаёт новое.
Args:
symbol:
Идентификатор торгового инструмента.
Returns:
Экземпляр TradeStreamState.
"""
state = self._states.get(symbol)
if state is None:
state = TradeStreamState(symbol=symbol)
self._states[symbol] = state
return state
def get(
self,
symbol: str,
) -> TradeStreamState:
"""
Возвращает существующее состояние.
Args:
symbol:
Идентификатор торгового инструмента.
Raises:
TradeStreamStateNotFoundError:
Если состояние отсутствует.
"""
try:
return self._states[symbol]
except KeyError as error:
raise TradeStreamStateNotFoundError(
f"Состояние Trade Stream для символа {symbol!r} не найдено."
) from error
def contains(
self,
symbol: str,
) -> bool:
"""
Проверяет наличие состояния.
Args:
symbol:
Идентификатор торгового инструмента.
Returns:
True, если состояние существует.
"""
return symbol in self._states
def remove(
self,
symbol: str,
) -> None:
"""
Удаляет состояние.
Args:
symbol:
Идентификатор торгового инструмента.
Raises:
TradeStreamStateNotFoundError:
Если состояние отсутствует.
"""
if symbol not in self._states:
raise TradeStreamStateNotFoundError(
f"Состояние Trade Stream для символа "
f"{symbol!r} не найдено."
)
del self._states[symbol]
def clear(self) -> None:
"""
Полностью очищает хранилище состояний.
"""
self._states.clear()

View File

@@ -0,0 +1,28 @@
# app/src/market_data/acquisition/consistency/trade_stream_state_store_exceptions.py
from __future__ import annotations
"""
Исключения хранилища состояний Trade Stream Consistency.
Build 060.20.1 вводит специализированное хранилище
состояния проверки согласованности потока сделок.
Исключения относятся исключительно к управлению
TradeStreamState и не описывают ошибки проверки
последовательности сделок.
"""
class TradeStreamStateStoreError(Exception):
"""
Базовое исключение хранилища состояний Trade Stream.
"""
class TradeStreamStateNotFoundError(
TradeStreamStateStoreError,
):
"""
Состояние торгового инструмента отсутствует.
"""

View File

@@ -0,0 +1,107 @@
# app/src/market_data/acquisition/consistency/trade_stream_state_store_protocol.py
from __future__ import annotations
"""
Протокол хранилища состояния Trade Stream Consistency.
Build 060.20.1 заменяет универсальный Trade Runtime Registry
специализированным типизированным хранилищем состояния
Canonical Trade Stream.
TradeStreamStateStoreProtocol определяет минимальный контракт
доступа к состоянию проверки согласованности потока сделок.
Протокол не описывает внутреннюю реализацию хранения
и не содержит бизнес-логики Trade Stream Consistency.
"""
from typing import Protocol, runtime_checkable
from src.market_data.acquisition.consistency.trade_stream_state import (
TradeStreamState,
)
@runtime_checkable
class TradeStreamStateStoreProtocol(Protocol):
"""
Протокол хранилища состояний Trade Stream Consistency.
"""
def get_or_create(
self,
symbol: str,
) -> TradeStreamState:
"""
Возвращает существующее состояние торгового инструмента
либо создаёт новое состояние при первом обращении.
Args:
symbol:
Идентификатор торгового инструмента.
Returns:
Существующий либо созданный TradeStreamState.
"""
...
def get(
self,
symbol: str,
) -> TradeStreamState:
"""
Возвращает существующее состояние торгового инструмента.
Args:
symbol:
Идентификатор торгового инструмента.
Returns:
Зарегистрированный TradeStreamState.
Raises:
TradeStreamStateNotFoundError:
Если состояние торгового инструмента отсутствует.
"""
...
def contains(
self,
symbol: str,
) -> bool:
"""
Проверяет наличие состояния торгового инструмента.
Args:
symbol:
Идентификатор торгового инструмента.
Returns:
True, если состояние существует,
иначе False.
"""
...
def remove(
self,
symbol: str,
) -> None:
"""
Удаляет состояние торгового инструмента.
Args:
symbol:
Идентификатор торгового инструмента.
Raises:
TradeStreamStateNotFoundError:
Если состояние торгового инструмента отсутствует.
"""
...
def clear(self) -> None:
"""
Полностью очищает хранилище состояний.
"""
...

View File

@@ -1,43 +0,0 @@
# app/src/market_data/acquisition/runtime/trade/trade_runtime_exceptions.py
from __future__ import annotations
"""
Инфраструктурные исключения Trade Runtime.
Build 060.20 вводит инфраструктурный слой Trade Runtime.
Данный модуль содержит только инфраструктурные исключения,
связанные с регистрацией и получением Runtime-компонентов.
Бизнес-исключения отдельных Runtime-модулей (Recovery,
Stream Consistency и других) должны оставаться
внутри соответствующих подсистем.
"""
class TradeRuntimeError(Exception):
"""
Базовый класс для всех инфраструктурных исключений Trade Runtime.
"""
class RuntimeAlreadyRegisteredError(TradeRuntimeError):
"""
Вызывается при попытке повторной регистрации Runtime-компонента
под уже существующим ключом.
"""
class RuntimeNotRegisteredError(TradeRuntimeError):
"""
Вызывается при попытке получить Runtime-компонент,
который отсутствует в TradeRuntimeRegistry.
"""
class InvalidRuntimeComponentError(TradeRuntimeError):
"""
Вызывается при попытке зарегистрировать объект,
который не может являться Runtime-компонентом.
"""

View File

@@ -1,85 +0,0 @@
# app/src/market_data/acquisition/runtime/trade/trade_runtime_protocol.py
from __future__ import annotations
"""
Протокол Trade Runtime.
Build 060.20 вводит единый Runtime Layer для управления
жизненным циклом компонентов, обеспечивающих обработку
биржевого потока сделок.
TradeRuntimeProtocol определяет минимальный контракт,
которому должна соответствовать реализация Runtime Registry.
Протокол не описывает внутреннюю реализацию хранения
компонентов и не содержит бизнес-логики.
"""
from typing import Any, Protocol
class TradeRuntimeProtocol(Protocol):
"""
Протокол реестра Runtime-компонентов.
"""
def register(self, key: str, component: Any) -> None:
"""
Регистрирует Runtime-компонент.
Args:
key:
Уникальный идентификатор Runtime-компонента.
component:
Экземпляр Runtime-компонента.
"""
...
def unregister(self, key: str) -> None:
"""
Удаляет Runtime-компонент из реестра.
Args:
key:
Уникальный идентификатор Runtime-компонента.
"""
...
def get(self, key: str) -> Any:
"""
Возвращает зарегистрированный Runtime-компонент.
Args:
key:
Уникальный идентификатор Runtime-компонента.
Returns:
Зарегистрированный Runtime-компонент.
Raises:
RuntimeNotRegisteredError:
Если компонент отсутствует в реестре.
"""
...
def is_registered(self, key: str) -> bool:
"""
Проверяет наличие Runtime-компонента в реестре.
Args:
key:
Уникальный идентификатор Runtime-компонента.
Returns:
True, если компонент зарегистрирован,
иначе False.
"""
...
def clear(self) -> None:
"""
Полностью очищает реестр Runtime-компонентов.
"""
...

View File

@@ -1,132 +0,0 @@
# app/src/market_data/acquisition/runtime/trade/trade_runtime_registry.py
from __future__ import annotations
"""
Реестр компонентов Trade Runtime.
Build 060.20 вводит единый инфраструктурный реестр,
который владеет экземплярами Runtime-компонентов
и предоставляет их по уникальным строковым ключам.
Реестр не управляет бизнес-состоянием компонентов
и не содержит логики Stream Consistency, Recovery
или других подсистем обработки потока сделок.
"""
from typing import Any
from src.market_data.acquisition.runtime.trade.trade_runtime_exceptions import (
InvalidRuntimeComponentError,
RuntimeAlreadyRegisteredError,
RuntimeNotRegisteredError,
)
from src.market_data.acquisition.runtime.trade.trade_runtime_protocol import (
TradeRuntimeProtocol,
)
class TradeRuntimeRegistry(TradeRuntimeProtocol):
"""
Реестр Runtime-компонентов потока сделок.
Каждый компонент регистрируется под уникальным строковым ключом.
Повторная регистрация под тем же ключом запрещена.
"""
def __init__(self) -> None:
"""
Создаёт пустой реестр Runtime-компонентов.
"""
self._components: dict[str, Any] = {}
def register(self, key: str, component: Any) -> None:
"""
Регистрирует Runtime-компонент под уникальным ключом.
Args:
key:
Уникальный идентификатор Runtime-компонента.
component:
Экземпляр Runtime-компонента.
Raises:
InvalidRuntimeComponentError:
Если вместо Runtime-компонента передан None.
RuntimeAlreadyRegisteredError:
Если указанный ключ уже используется.
"""
if component is None:
raise InvalidRuntimeComponentError(
f"Runtime-компонент для ключа {key!r} не может быть None."
)
if key in self._components:
raise RuntimeAlreadyRegisteredError(
f"Runtime-компонент с ключом {key!r} уже зарегистрирован."
)
self._components[key] = component
def unregister(self, key: str) -> None:
"""
Удаляет Runtime-компонент из реестра.
Args:
key:
Уникальный идентификатор Runtime-компонента.
Raises:
RuntimeNotRegisteredError:
Если компонент с указанным ключом отсутствует.
"""
if key not in self._components:
raise RuntimeNotRegisteredError(
f"Runtime-компонент с ключом {key!r} не зарегистрирован."
)
del self._components[key]
def get(self, key: str) -> Any:
"""
Возвращает зарегистрированный Runtime-компонент.
Args:
key:
Уникальный идентификатор Runtime-компонента.
Returns:
Зарегистрированный Runtime-компонент.
Raises:
RuntimeNotRegisteredError:
Если компонент с указанным ключом отсутствует.
"""
try:
return self._components[key]
except KeyError as error:
raise RuntimeNotRegisteredError(
f"Runtime-компонент с ключом {key!r} не зарегистрирован."
) from error
def is_registered(self, key: str) -> bool:
"""
Проверяет наличие Runtime-компонента в реестре.
Args:
key:
Уникальный идентификатор Runtime-компонента.
Returns:
True, если компонент зарегистрирован,
иначе False.
"""
return key in self._components
def clear(self) -> None:
"""
Удаляет из реестра все зарегистрированные Runtime-компоненты.
"""
self._components.clear()