fix: harden skipped ledger resolution paths
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
co-authored by
genichin
parent
b88b21b772
commit
48dfc3e76f
@@ -25,10 +25,11 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import random
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass, replace
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from enum import Enum
|
||||
from typing import Callable, Optional, Protocol
|
||||
from typing import Optional, Protocol
|
||||
|
||||
from trex_core.application.alarm_emitter import AlarmEmitter
|
||||
from trex_core.application.ledger_port import (
|
||||
@@ -39,6 +40,7 @@ from trex_core.application.ledger_port import (
|
||||
LedgerTrade,
|
||||
LedgerWriteResult,
|
||||
)
|
||||
from trex_core.application.ledger_skip import publish_ledger_skip_alarm
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
@@ -171,6 +173,8 @@ class LedgerWriter:
|
||||
clock: Optional[Callable[[], datetime]] = None,
|
||||
rng: Optional[Callable[[], float]] = None,
|
||||
alarm_emitter: Optional[AlarmEmitter] = None,
|
||||
ledger_skip_store=None,
|
||||
instance_key: str | None = None,
|
||||
) -> None:
|
||||
self._outbox = outbox
|
||||
self._ledger = ledger
|
||||
@@ -185,6 +189,8 @@ class LedgerWriter:
|
||||
self._rng = rng or random.random # jitter source; inject for determinism
|
||||
# dcy-033 / REQ-100: best-effort alarm emitter.
|
||||
self._alarm_emitter = alarm_emitter
|
||||
self._ledger_skip_store = ledger_skip_store
|
||||
self._instance_key = instance_key
|
||||
|
||||
def enqueue_fill(self, trade: LedgerTrade) -> LedgerWorkItem:
|
||||
return self._outbox.enqueue(trade)
|
||||
@@ -301,10 +307,32 @@ class LedgerWriter:
|
||||
# execution_id either way (REQ-019 AC-1, AC-4).
|
||||
if outcome.result is LedgerWriteResult.DUPLICATE_OK:
|
||||
self._outbox.mark_outcome(item.correlation_id, OutboxOutcome.DUPLICATE_COMPLETED)
|
||||
self._resolve_ledger_skip(item.trade)
|
||||
return OutboxOutcome.DUPLICATE_COMPLETED
|
||||
self._outbox.mark_outcome(item.correlation_id, OutboxOutcome.COMPLETED)
|
||||
self._resolve_ledger_skip(item.trade)
|
||||
return OutboxOutcome.COMPLETED
|
||||
|
||||
def _resolve_ledger_skip(self, trade: LedgerTrade) -> None:
|
||||
if (
|
||||
self._ledger_skip_store is None
|
||||
or self._instance_key is None
|
||||
or not trade.asset_id
|
||||
or not trade.order_id
|
||||
or not trade.execution_id
|
||||
):
|
||||
return
|
||||
records = self._ledger_skip_store.resolve_for_delivery(
|
||||
instance_key=self._instance_key,
|
||||
portfolio_id=trade.asset_id,
|
||||
side=trade.side,
|
||||
order_id=trade.order_id,
|
||||
execution_id=trade.execution_id,
|
||||
resolution_reason="ledger_recorded",
|
||||
)
|
||||
for record in records:
|
||||
publish_ledger_skip_alarm(self._alarm_emitter, record, resolved=True)
|
||||
|
||||
def _writeback(self, trade: LedgerTrade, outcome) -> None:
|
||||
"""Option D cash/quantity write-back (dcy-018). best-effort; skips when
|
||||
no SnapshotStore is wired or the response omits authoritative values."""
|
||||
|
||||
Reference in New Issue
Block a user