fix(execution): cancel SQL nullable type error, KIS child cancel detection, worker exception logging

Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-09-01 03:33:38 +00:00
committed by GitHub
co-authored by genichin
parent 2b412fd786
commit f0ac909958
6 changed files with 258 additions and 12 deletions
+28 -11
View File
@@ -385,20 +385,37 @@ class PostgreSQLSlotRepository:
*,
retry_before: Optional[datetime] = None,
) -> bool:
"""Atomically reserve first cancel or an authoritative backoff-gated retry."""
"""Atomically reserve first cancel or an authoritative backoff-gated retry.
Two separate SQL paths avoid nullable-placeholder type-inference errors
(PostgreSQL IndeterminateDatatype when binding None to %s IS NOT NULL).
"""
now = datetime.now(tz=timezone.utc)
with self._psycopg.connect(self._dsn, autocommit=False) as conn:
with conn.cursor() as cur:
cur.execute(
"UPDATE daily_slot SET cancel_state='unknown', cancel_requested_at=%s, "
"cancel_attempts=cancel_attempts+1, updated_at=%s "
"WHERE slot_id=%s AND broker_order_id=%s "
"AND status IN ('pending_buy','pending_sell') "
"AND (cancel_state IS NULL OR "
"(%s IS NOT NULL AND cancel_state IN ('rejected','unknown') "
"AND cancel_attempts < 4 AND cancel_requested_at <= %s))",
(now, now, slot_id, broker_order_id, retry_before, retry_before),
)
if retry_before is None:
# First reservation: only match when no cancel has been
# attempted yet (cancel_state IS NULL).
cur.execute(
"UPDATE daily_slot SET cancel_state='unknown', cancel_requested_at=%s, "
"cancel_attempts=cancel_attempts+1, updated_at=%s "
"WHERE slot_id=%s AND broker_order_id=%s "
"AND status IN ('pending_buy','pending_sell') "
"AND cancel_state IS NULL",
(now, now, slot_id, broker_order_id),
)
else:
# Retry: backoff-gated, only match retryable states.
cur.execute(
"UPDATE daily_slot SET cancel_state='unknown', cancel_requested_at=%s, "
"cancel_attempts=cancel_attempts+1, updated_at=%s "
"WHERE slot_id=%s AND broker_order_id=%s "
"AND status IN ('pending_buy','pending_sell') "
"AND cancel_state IN ('rejected','unknown') "
"AND cancel_attempts < 4 "
"AND cancel_requested_at <= %s",
(now, now, slot_id, broker_order_id, retry_before),
)
ok = cur.rowcount == 1
conn.commit()
return ok