Build 060.22: implement Acquisition Runtime Service

This commit is contained in:
2026-07-27 07:48:57 +03:00
parent 433ac5d375
commit 9953bab993
7 changed files with 3233 additions and 4 deletions

View File

@@ -0,0 +1,136 @@
# app/src/market_data/acquisition/runtime/acquisition_runtime_service.py
from __future__ import annotations
"""
Сервис исполнения команд Acquisition Runtime.
Build 060.22 вводит первую производственную реализацию
сервисного слоя Runtime подсистемы Market Data Acquisition.
Сервис принимает типизированные Runtime-команды и делегирует
их выполнение соответствующим инфраструктурным зависимостям.
Сервис не содержит знаний о Trades Feed, Consistency или Recovery.
"""
from src.market_data.acquisition.runtime.acquisition_runtime_service_protocol import (
AcquisitionRuntimeServiceProtocol,
)
from src.market_data.acquisition.runtime.runtime_commands import (
ConnectCommand,
DisconnectCommand,
SendBinaryCommand,
SendTextCommand,
SubscribeCommand,
UnsubscribeCommand,
)
from src.market_data.acquisition.runtime.websocket_protocol import (
AcquisitionRuntimeCommand,
AcquisitionRuntimeCommandDispatcherProtocol,
AcquisitionRuntimeEventPublisherProtocol,
WebSocketSessionProtocol,
WebSocketSubscriptionManagerProtocol,
WebSocketTransportProtocol,
)
class AcquisitionRuntimeService(
AcquisitionRuntimeServiceProtocol,
AcquisitionRuntimeCommandDispatcherProtocol,
):
"""
Сервис маршрутизации Acquisition Runtime Commands.
Каждая команда делегируется ровно одной инфраструктурной
зависимости.
Сервис не управляет reconnect, heartbeat, scheduler,
Recovery или обработкой рыночных данных.
"""
def __init__(
self,
session: WebSocketSessionProtocol,
transport: WebSocketTransportProtocol,
subscription_manager: WebSocketSubscriptionManagerProtocol,
event_publisher: AcquisitionRuntimeEventPublisherProtocol,
) -> None:
"""
Создать Acquisition Runtime Service.
Args:
session:
Компонент жизненного цикла WebSocket-сессии.
transport:
Низкоуровневый WebSocket-транспорт.
subscription_manager:
Компонент управления активными подписками.
event_publisher:
Компонент публикации инфраструктурных Runtime-событий.
В Build 060.22 зависимость сохраняется как часть
утверждённой архитектуры, но публикация событий
будет подключена в последующих Build.
"""
self._session = session
self._transport = transport
self._subscription_manager = subscription_manager
self._event_publisher = event_publisher
async def dispatch(
self,
command: AcquisitionRuntimeCommand,
) -> None:
"""
Выполнить одну инфраструктурную команду Acquisition Runtime.
Args:
command:
Типизированная команда Runtime Layer.
Raises:
TypeError:
Если передан неподдерживаемый тип команды.
Exception:
Любое исключение инфраструктурной зависимости
распространяется вызывающему компоненту без изменения.
"""
if isinstance(command, ConnectCommand):
await self._session.start()
return
if isinstance(command, DisconnectCommand):
await self._session.stop()
return
if isinstance(command, SubscribeCommand):
await self._subscription_manager.subscribe(
command.subscription_key,
command.message,
)
return
if isinstance(command, UnsubscribeCommand):
await self._subscription_manager.unsubscribe(
command.subscription_key,
command.message,
)
return
if isinstance(command, SendTextCommand):
await self._transport.send(command.message.payload)
return
if isinstance(command, SendBinaryCommand):
await self._transport.send(command.message.payload)
return
raise TypeError(
"Неподдерживаемый тип Acquisition Runtime Command: "
f"{type(command).__name__}."
)

View File

@@ -0,0 +1,44 @@
# app/src/market_data/acquisition/runtime/acquisition_runtime_service_protocol.py
from __future__ import annotations
"""
Публичный контракт Acquisition Runtime Service.
Build 060.22 вводит сервисный уровень исполнения типизированных
команд Runtime подсистемы Market Data Acquisition.
Контракт не определяет устройство WebSocket Session, Transport,
Subscription Manager или механизма публикации событий.
"""
from typing import Protocol, runtime_checkable
from src.market_data.acquisition.runtime.websocket_protocol import (
AcquisitionRuntimeCommand,
)
@runtime_checkable
class AcquisitionRuntimeServiceProtocol(Protocol):
"""
Контракт сервиса исполнения Acquisition Runtime Commands.
Реализация принимает одну типизированную команду и передаёт её
соответствующей инфраструктурной зависимости.
Сервис не содержит знаний о Trades Feed, Consistency и Recovery.
"""
async def dispatch(
self,
command: AcquisitionRuntimeCommand,
) -> None:
"""
Выполнить одну инфраструктурную команду Acquisition Runtime.
Args:
command:
Типизированная команда Runtime Layer.
"""
...

View File

@@ -23,6 +23,10 @@ from src.market_data.acquisition.runtime.runtime_events import (
ReconnectFailedEvent,
ReconnectStartedEvent,
)
from src.market_data.acquisition.runtime.transport_messages import (
TransportBinaryMessage,
TransportTextMessage,
)
AcquisitionRuntimeCommand = (
@@ -46,6 +50,11 @@ AcquisitionRuntimeEvent = (
| HeartbeatTimeoutEvent
)
AcquisitionSubscriptionMessage = (
TransportTextMessage
| TransportBinaryMessage
)
@runtime_checkable
class WebSocketTransportProtocol(Protocol):
@@ -108,10 +117,50 @@ class WebSocketSubscriptionManagerProtocol(Protocol):
"""
Контракт управления активными WebSocket-подписками.
Конкретные модели подписок и формат сообщений будут добавлены
в последующих Build'ах.
Subscription Manager отвечает за регистрацию и удаление
активных подписок, а также за восстановление зарегистрированных
подписок после повторного подключения.
Менеджер работает только с универсальными транспортными
сообщениями и не содержит exchange-specific логики.
"""
async def subscribe(
self,
subscription_key: str,
message: AcquisitionSubscriptionMessage,
) -> None:
"""
Зарегистрировать и выполнить WebSocket-подписку.
Args:
subscription_key:
Уникальный инфраструктурный ключ подписки.
message:
Полностью сформированное транспортное сообщение
подписки.
"""
...
async def unsubscribe(
self,
subscription_key: str,
message: AcquisitionSubscriptionMessage,
) -> None:
"""
Отменить и удалить существующую WebSocket-подписку.
Args:
subscription_key:
Уникальный инфраструктурный ключ подписки.
message:
Полностью сформированное транспортное сообщение
отмены подписки.
"""
...
async def restore_subscriptions(self) -> None:
"""Восстановить активные подписки после подключения."""
...
@@ -162,4 +211,4 @@ class AcquisitionRuntimeEventPublisherProtocol(Protocol):
"""
Опубликовать одно инфраструктурное событие Runtime.
"""
...
...