Build 060.27: implement Persistent Market Data Storage

This commit is contained in:
2026-08-01 03:22:25 +03:00
parent cb8acfe5fe
commit 58e5a12a4d
54 changed files with 10243 additions and 101 deletions

View File

@@ -1,13 +1,28 @@
from __future__ import annotations
from typing import Any
from src.bootstrap.trade_stream_runtime import (
build_trade_stream_production_runtime,
)
from src.core.config import Settings, TradeStreamSettings
from src.core.config import (
MarketDataStorageSettings,
Settings,
TradeStreamSettings,
)
from src.market_data.acquisition.runtime.trade_stream_production_runtime import (
TradeStreamProductionRuntime,
TradeStreamProductionRuntimeState,
)
from src.market_data.acquisition.models.trade import Trade
class RecordingTradeObservationSink:
def __init__(self) -> None:
self.observations: list[Trade] = []
def persist(self, trade: Trade) -> None:
self.observations.append(trade)
def make_settings(
@@ -49,6 +64,12 @@ def make_settings(
db_name="test",
db_user="test",
db_password="test",
market_data_storage=MarketDataStorageSettings(
enabled=False,
pool_min_size=1,
pool_max_size=4,
pool_timeout_seconds=10.0,
),
debug_enabled=False,
journal_debug_enabled=False,
)
@@ -80,33 +101,60 @@ def test_uses_one_shared_stateful_dependency_graph() -> None:
assert isinstance(runtime, TradeStreamProductionRuntime)
transport = runtime._transport
service = runtime._trade_stream_service
reconnect_recovery = runtime._reconnect_recovery_coordinator
runtime_graph: Any = runtime
transport = runtime_graph._transport
service = runtime_graph._trade_stream_service
reconnect_recovery = runtime_graph._reconnect_recovery_coordinator
recovery = reconnect_recovery._recovery_coordinator
assert runtime._session._transport is transport
assert runtime._subscription_manager._transport is transport
assert runtime._runtime_scheduler.liveness_probe is transport
assert runtime_graph._session._transport is transport
assert runtime_graph._subscription_manager._transport is transport
assert runtime_graph._runtime_scheduler.liveness_probe is transport
assert (
service._consistency_controller
is recovery._recovery_controller._consistency_controller
)
assert runtime._live_processing_gate is (
assert runtime_graph._live_processing_gate is (
reconnect_recovery.live_processing_gate
)
assert runtime._runtime_scheduler.runtime_supervisor is (
runtime._runtime_supervisor
assert runtime_graph._runtime_scheduler.runtime_supervisor is (
runtime_graph._runtime_supervisor
)
def test_optional_storage_sink_is_shared_by_live_and_recovery() -> None:
sink = RecordingTradeObservationSink()
runtime = build_trade_stream_production_runtime(
make_settings(),
trade_observation_sink=sink,
)
assert isinstance(runtime, TradeStreamProductionRuntime)
runtime_graph: Any = runtime
live_controller = (
runtime_graph._trade_stream_service._consistency_controller
)
recovery_controller = (
runtime_graph
._reconnect_recovery_coordinator
._recovery_coordinator
._recovery_controller
._consistency_controller
)
assert live_controller is recovery_controller
assert live_controller._trade_observation_sink is sink
def test_applies_explicit_transport_and_runtime_settings() -> None:
settings = make_settings()
runtime = build_trade_stream_production_runtime(settings)
assert isinstance(runtime, TradeStreamProductionRuntime)
transport = runtime._transport
runtime_graph: Any = runtime
transport = runtime_graph._transport
assert transport._url == "wss://stream.example.test/root/connect"
assert transport._headers == {
@@ -119,17 +167,17 @@ def test_applies_explicit_transport_and_runtime_settings() -> None:
assert transport._close_timeout == 9.0
assert transport._ping_interval is None
assert transport._ping_timeout is None
assert runtime._symbols == (
assert runtime_graph._symbols == (
"BTC/USD_LEVERAGE",
"ETH/USD_LEVERAGE",
)
assert runtime._runtime_scheduler.interval_seconds == 6.0
assert runtime_graph._runtime_scheduler.interval_seconds == 6.0
assert (
runtime._runtime_supervisor._heartbeat_monitor.timeout_seconds
runtime_graph._runtime_supervisor._heartbeat_monitor.timeout_seconds
== 31.0
)
assert (
runtime._reconnect_recovery_coordinator
runtime_graph._reconnect_recovery_coordinator
._recovery_coordinator
._window_planner
.max_window_ms
@@ -143,8 +191,9 @@ def test_recovery_rest_client_reuses_settings_snapshot() -> None:
runtime = build_trade_stream_production_runtime(settings)
assert isinstance(runtime, TradeStreamProductionRuntime)
runtime_graph: Any = runtime
document_source = (
runtime._reconnect_recovery_coordinator
runtime_graph._reconnect_recovery_coordinator
._recovery_coordinator
._recovery_controller
._document_source
@@ -154,4 +203,4 @@ def test_recovery_rest_client_reuses_settings_snapshot() -> None:
assert rest_client.settings is settings
assert rest_client.base_url == "https://rest.example.test"
assert rest_client.timeout == 17
assert "X-MBX-APIKEY" not in runtime._transport._headers
assert "X-MBX-APIKEY" not in runtime_graph._transport._headers