fix(trigger): recover interrupted deliveries

This commit is contained in:
chengyongru
2026-07-02 13:32:46 +08:00
committed by Xubin Ren
parent 55b550ee01
commit 1ed2c9a213
7 changed files with 133 additions and 14 deletions
+66
View File
@@ -49,6 +49,33 @@ def test_enqueue_rejects_disabled_trigger(tmp_path: Path) -> None:
store.enqueue(trigger.id, "Review PR #4502")
def test_recover_processing_deliveries_requeues_claimed_delivery(tmp_path: Path) -> None:
store = ExternalTriggerStore(tmp_path)
trigger = store.create(
name="PR review",
channel="websocket",
chat_id="chat-1",
session_key="websocket:chat-1",
)
store.enqueue(trigger.id, "Review PR #4591")
claimed = store.claim_deliveries()
assert len(claimed) == 1
assert claimed[0].path is not None
assert claimed[0].path.parent.name == "processing"
assert ExternalTriggerStore(tmp_path).claim_deliveries() == []
restarted = ExternalTriggerStore(tmp_path)
assert restarted.recover_processing_deliveries() == 1
reclaimed = restarted.claim_deliveries()
assert len(reclaimed) == 1
assert reclaimed[0].trigger_id == trigger.id
assert reclaimed[0].content == "Review PR #4591"
assert reclaimed[0].attempts == 1
assert reclaimed[0].last_error == "delivery was recovered from interrupted processing"
@pytest.mark.asyncio
async def test_external_trigger_queue_publishes_bound_inbound_message(tmp_path: Path) -> None:
store = ExternalTriggerStore(tmp_path)
@@ -99,3 +126,42 @@ async def test_external_trigger_queue_publishes_bound_inbound_message(tmp_path:
assert stored.last_status == "ok"
assert stored.last_run_at_ms is not None
assert store.claim_deliveries() == []
@pytest.mark.asyncio
async def test_external_trigger_queue_recovers_processing_delivery_on_start(
tmp_path: Path,
) -> None:
store = ExternalTriggerStore(tmp_path)
trigger = store.create(
name="PR review",
channel="websocket",
chat_id="chat-1",
session_key="websocket:chat-1",
)
store.enqueue(trigger.id, "Review PR #4591")
assert len(store.claim_deliveries()) == 1
published: list[InboundMessage] = []
class _Bus:
async def publish_inbound(self, msg: InboundMessage) -> None:
published.append(msg)
restarted = ExternalTriggerStore(tmp_path)
task = asyncio.create_task(
run_external_trigger_queue(store=restarted, bus=_Bus(), poll_interval_s=0.01)
)
try:
for _ in range(100):
if published:
break
await asyncio.sleep(0.01)
finally:
task.cancel()
with suppress(asyncio.CancelledError):
await task
assert len(published) == 1
assert published[0].content == "Review PR #4591"
assert published[0].metadata["_external_trigger"]["trigger_id"] == trigger.id
assert restarted.claim_deliveries() == []