Build 060.22: implement Acquisition Runtime Service
This commit is contained in:
@@ -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__}."
|
||||
)
|
||||
@@ -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.
|
||||
"""
|
||||
...
|
||||
@@ -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.
|
||||
"""
|
||||
...
|
||||
...
|
||||
Reference in New Issue
Block a user