blackout: enforce bounded oldest-drop queue policy on overflow (#371)
All checks were successful
Gitea CI / test (push) Successful in 33s
Gitea CI / test (pull_request) Successful in 33s

This commit is contained in:
agentson
2026-03-02 02:57:08 +09:00
parent f7e242d147
commit 7959b749c7
6 changed files with 124 additions and 6 deletions

View File

@@ -68,11 +68,16 @@ class BlackoutOrderManager:
self._queue: deque[QueuedOrderIntent] = deque()
self._was_blackout = False
self._max_queue_size = max_queue_size
self._overflow_drop_count = 0
@property
def pending_count(self) -> int:
return len(self._queue)
@property
def overflow_drop_count(self) -> int:
return self._overflow_drop_count
def in_blackout(self, now: datetime | None = None) -> bool:
if not self.enabled or not self._windows:
return False
@@ -81,8 +86,11 @@ class BlackoutOrderManager:
return any(window.contains(kst_now) for window in self._windows)
def enqueue(self, intent: QueuedOrderIntent) -> bool:
if len(self._queue) >= self._max_queue_size:
if self._max_queue_size <= 0:
return False
if len(self._queue) >= self._max_queue_size:
self._queue.popleft()
self._overflow_drop_count += 1
self._queue.append(intent)
return True

View File

@@ -1031,9 +1031,19 @@ def _maybe_queue_order_intent(
price: float,
source: str,
) -> bool:
def _coerce_nonnegative_int(value: Any) -> int:
try:
parsed = int(value)
except (TypeError, ValueError):
return 0
return max(0, parsed)
if not BLACKOUT_ORDER_MANAGER.in_blackout():
return False
before_overflow_drops = _coerce_nonnegative_int(
getattr(BLACKOUT_ORDER_MANAGER, "overflow_drop_count", 0)
)
queued = BLACKOUT_ORDER_MANAGER.enqueue(
_build_queued_order_intent(
market=market,
@@ -1045,6 +1055,9 @@ def _maybe_queue_order_intent(
)
)
if queued:
after_overflow_drops = _coerce_nonnegative_int(
getattr(BLACKOUT_ORDER_MANAGER, "overflow_drop_count", 0)
)
logger.warning(
(
"Blackout active: queued order intent %s %s (%s) "
@@ -1058,9 +1071,22 @@ def _maybe_queue_order_intent(
source,
BLACKOUT_ORDER_MANAGER.pending_count,
)
if after_overflow_drops > before_overflow_drops:
logger.error(
(
"Blackout queue overflow policy applied: evicted oldest intent "
"to keep latest %s %s (%s) source=%s pending=%d total_evicted=%d"
),
order_type,
stock_code,
market.code,
source,
BLACKOUT_ORDER_MANAGER.pending_count,
after_overflow_drops,
)
else:
logger.error(
"Blackout queue full: dropped order intent %s %s (%s) qty=%d source=%s",
"Blackout queue unavailable: could not queue order intent %s %s (%s) qty=%d source=%s",
order_type,
stock_code,
market.code,