fix: drain authored actions on shutdown (#461)
CI / lint (pull_request) Successful in 51s
CI / build-release (pull_request) Successful in 5s
CI / release-candidate (pull_request) Has been skipped

This commit is contained in:
timmy committed 2026-08-10 07:12:51 +00:00
1 parent 8e6ee96ede
commit 0dd3932d14
3 files changed
+108 -1

No files matched your search

+76
View File
@@ -306,3 +306,79 @@ async def test_application_shutdown_cancels_available_work_scan_before_transport
main._available_issue_snapshot_task = None
assert calls == ["start", "available scan cancelled", "stop (done)"]
@pytest.mark.anyio
async def test_application_shutdown_drains_authored_mutation_before_transport(monkeypatch):
calls = []
started = asyncio.Event()
release = asyncio.Event()
async def authored_mutation():
started.set()
await release.wait()
calls.append("mutation persisted")
return {"id": 461}
monkeypatch.setattr(gitea_proxy, "start_client", lambda: calls.append("start"))
async def stop_client():
calls.append("stop")
monkeypatch.setattr(gitea_proxy, "stop_client", stop_client)
context = main.app.router.lifespan_context(main.app)
await context.__aenter__()
task = asyncio.create_task(authored_mutation())
main._authored_action_operations["shutdown-drain-461"] = (
("comment", "stackchain/dashboard", 461),
task,
0.0,
)
await started.wait()
shutdown = asyncio.create_task(context.__aexit__(None, None, None))
await asyncio.sleep(0)
assert not shutdown.done()
assert calls == ["start"]
release.set()
await shutdown
assert calls == ["start", "mutation persisted", "stop"]
@pytest.mark.anyio
async def test_application_shutdown_bounds_and_settles_stalled_authored_mutation(monkeypatch):
calls = []
started = asyncio.Event()
async def stalled_mutation():
started.set()
try:
await asyncio.Event().wait()
finally:
calls.append("mutation cancelled")
monkeypatch.setattr(main, "AUTHORED_ACTION_SHUTDOWN_GRACE_SECONDS", 0.01)
monkeypatch.setattr(gitea_proxy, "start_client", lambda: calls.append("start"))
async def stop_client():
calls.append("stop")
monkeypatch.setattr(gitea_proxy, "stop_client", stop_client)
context = main.app.router.lifespan_context(main.app)
await context.__aenter__()
task = asyncio.create_task(stalled_mutation())
main._authored_action_operations["stalled-shutdown-461"] = (
("review", "stackchain/dashboard", 461),
task,
0.0,
)
await started.wait()
await asyncio.wait_for(context.__aexit__(None, None, None), timeout=0.2)
assert task.cancelled()
assert main._authored_action_operations == {}
assert calls == ["start", "mutation cancelled", "stop"]