PINK Phase 0 and 1: VST WS confirmed plus AccountSnapshotV2 account core
This commit is contained in:
@@ -1,102 +0,0 @@
|
||||
"""Debug journaling surfaces for DITAv2."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Callable, Dict, List, Optional, Protocol
|
||||
|
||||
from .contracts import KernelTransition, TradeSlot, TradeStage, VenueEvent
|
||||
from .control import KernelControlSnapshot
|
||||
from .utils import json_safe, json_text
|
||||
|
||||
JournalSink = Callable[[str, Dict[str, Any]], None]
|
||||
|
||||
|
||||
class KernelJournal(Protocol):
|
||||
"""Append-only debug journal interface."""
|
||||
|
||||
def record(self, row: Dict[str, Any]) -> None:
|
||||
...
|
||||
|
||||
def record_transition(
|
||||
self,
|
||||
*,
|
||||
transition: KernelTransition,
|
||||
slot: TradeSlot,
|
||||
event: Optional[VenueEvent] = None,
|
||||
control: Optional[KernelControlSnapshot] = None,
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
@dataclass
|
||||
class MemoryKernelJournal:
|
||||
"""In-memory journal used in tests."""
|
||||
|
||||
rows: List[Dict[str, Any]] = field(default_factory=list)
|
||||
capture_limit: int = 10_000
|
||||
|
||||
def record(self, row: Dict[str, Any]) -> None:
|
||||
if len(self.rows) < self.capture_limit:
|
||||
self.rows.append(dict(row))
|
||||
|
||||
def record_transition(
|
||||
self,
|
||||
*,
|
||||
transition: KernelTransition,
|
||||
slot: TradeSlot,
|
||||
event: Optional[VenueEvent] = None,
|
||||
control: Optional[KernelControlSnapshot] = None,
|
||||
) -> None:
|
||||
row = _transition_row(transition=transition, slot=slot, event=event, control=control)
|
||||
self.record(row)
|
||||
|
||||
|
||||
class ClickHouseKernelJournal:
|
||||
"""Fire-and-forget ClickHouse journal.
|
||||
|
||||
The sink is a small callable of the form ``sink(table_name, row_dict)``.
|
||||
"""
|
||||
|
||||
def __init__(self, sink: Optional[JournalSink] = None):
|
||||
self.sink = sink
|
||||
|
||||
def record(self, row: Dict[str, Any]) -> None:
|
||||
if self.sink is not None:
|
||||
self.sink("dita_kernel_debug", row)
|
||||
|
||||
def record_transition(
|
||||
self,
|
||||
*,
|
||||
transition: KernelTransition,
|
||||
slot: TradeSlot,
|
||||
event: Optional[VenueEvent] = None,
|
||||
control: Optional[KernelControlSnapshot] = None,
|
||||
) -> None:
|
||||
self.record(_transition_row(transition=transition, slot=slot, event=event, control=control))
|
||||
|
||||
|
||||
def _transition_row(
|
||||
*,
|
||||
transition: KernelTransition,
|
||||
slot: TradeSlot,
|
||||
event: Optional[VenueEvent],
|
||||
control: Optional[KernelControlSnapshot],
|
||||
) -> Dict[str, Any]:
|
||||
return {
|
||||
"ts": transition.timestamp.isoformat() if hasattr(transition.timestamp, "isoformat") else str(transition.timestamp),
|
||||
"trade_id": transition.trade_id,
|
||||
"slot_id": transition.slot_id,
|
||||
"prev_state": transition.prev_state.value,
|
||||
"next_state": transition.next_state.value,
|
||||
"trigger": transition.trigger,
|
||||
"intent_id": transition.intent_id,
|
||||
"event_id": transition.event_id,
|
||||
"control_mode": transition.control_mode,
|
||||
"control_verbosity": transition.control_verbosity,
|
||||
"slot_state": slot.to_dict(),
|
||||
"event_payload": json_safe(event) if event is not None else {},
|
||||
"control_snapshot": control.as_dict() if control is not None else {},
|
||||
"slot_state_json": json_text(slot.to_dict()),
|
||||
}
|
||||
Reference in New Issue
Block a user