feat(execution): reconcile timed-out orders safely
This commit is contained in:
@@ -290,7 +290,8 @@ class TestTimeoutCancel:
|
||||
# age the slot past timeout
|
||||
s = repo.fetch_slot(sid)
|
||||
repo._slots[sid] = replace(
|
||||
s, updated_at=datetime.now(tz=timezone.utc) - timedelta(seconds=60),
|
||||
s,
|
||||
order_submitted_at=datetime.now(tz=timezone.utc) - timedelta(seconds=60),
|
||||
)
|
||||
r = execution.run_once()
|
||||
assert r.timeout_cancelled == 1
|
||||
@@ -310,13 +311,13 @@ class TestTimeoutCancel:
|
||||
assert r.timeout_cancelled == 0
|
||||
assert len(broker.cancel_calls) == 0
|
||||
|
||||
def test_no_timeout_sec_no_cancel(self):
|
||||
def test_updated_at_does_not_move_hard_fallback_deadline(self):
|
||||
broker = _RecordingBroker()
|
||||
repo, svc, intents, execution = _wire(broker)
|
||||
sid = _buy_to_pending(intents, timeout_sec=None)
|
||||
broker.responder = lambda side: FillStatus(state="accepted")
|
||||
execution.run_once() # dispatch
|
||||
# age the slot
|
||||
# Mutable row bookkeeping is not the dispatch/deadline clock.
|
||||
s = repo.fetch_slot(sid)
|
||||
repo._slots[sid] = replace(
|
||||
s, updated_at=datetime.now(tz=timezone.utc) - timedelta(seconds=9999),
|
||||
@@ -335,7 +336,8 @@ class TestTimeoutCancel:
|
||||
execution.run_once() # dispatch
|
||||
s = repo.fetch_slot(sid)
|
||||
repo._slots[sid] = replace(
|
||||
s, updated_at=datetime.now(tz=timezone.utc) - timedelta(seconds=60),
|
||||
s,
|
||||
order_submitted_at=datetime.now(tz=timezone.utc) - timedelta(seconds=60),
|
||||
)
|
||||
with caplog.at_level(logging.WARNING):
|
||||
r = execution.run_once()
|
||||
@@ -357,7 +359,8 @@ class TestTimeoutCancel:
|
||||
execution.run_once()
|
||||
s = repo.fetch_slot(sid)
|
||||
repo._slots[sid] = replace(
|
||||
s, updated_at=datetime.now(tz=timezone.utc) - timedelta(seconds=60),
|
||||
s,
|
||||
order_submitted_at=datetime.now(tz=timezone.utc) - timedelta(seconds=60),
|
||||
)
|
||||
execution.run_once()
|
||||
# slot still PENDING_BUY — cancel is best-effort; rollback on next poll
|
||||
@@ -376,7 +379,7 @@ class TestTimeoutCancel:
|
||||
slot = repo.fetch_slot(sid)
|
||||
repo._slots[sid] = replace(
|
||||
slot,
|
||||
updated_at=datetime.now(tz=timezone.utc) - timedelta(seconds=60),
|
||||
order_submitted_at=datetime.now(tz=timezone.utc) - timedelta(seconds=60),
|
||||
)
|
||||
|
||||
result = execution.run_once()
|
||||
@@ -395,7 +398,8 @@ class TestTimeoutCancel:
|
||||
# age the slot → cancel sent
|
||||
s = repo.fetch_slot(sid)
|
||||
repo._slots[sid] = replace(
|
||||
s, updated_at=datetime.now(tz=timezone.utc) - timedelta(seconds=60),
|
||||
s,
|
||||
order_submitted_at=datetime.now(tz=timezone.utc) - timedelta(seconds=60),
|
||||
)
|
||||
r1 = execution.run_once()
|
||||
assert r1.timeout_cancelled == 1
|
||||
|
||||
Reference in New Issue
Block a user