fix(agent): cache runtime receipt readback under db pool pressure
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / tests (push) Has been cancelled

This commit is contained in:
Your Name
2026-07-01 21:33:27 +08:00
parent d045db3e9f
commit 2cfb891e57
2 changed files with 188 additions and 3 deletions

View File

@@ -210,6 +210,8 @@ def _assert_log_controlled_writeback_consumer(payload: dict):
async def test_live_runtime_receipt_keeps_consumer_readback_when_trace_query_fails(
monkeypatch,
):
runtime_control_module._clear_runtime_receipt_readback_cache()
async def _fake_consumer_readback(*, project_id: str):
assert project_id == "awoooi"
return _log_controlled_writeback_consumer_readback()
@@ -225,9 +227,12 @@ async def test_live_runtime_receipt_keeps_consumer_readback_when_trace_query_fai
_fake_consumer_readback,
)
readback = (
await runtime_control_module.load_ai_agent_autonomous_runtime_receipt_readback()
)
try:
readback = (
await runtime_control_module.load_ai_agent_autonomous_runtime_receipt_readback()
)
finally:
runtime_control_module._clear_runtime_receipt_readback_cache()
assert readback["db_read_status"] == "unavailable"
assert readback["error"]["type"] == "RuntimeError"
@@ -236,6 +241,99 @@ async def test_live_runtime_receipt_keeps_consumer_readback_when_trace_query_fai
)
@pytest.mark.asyncio
async def test_live_runtime_receipt_readback_uses_short_cache_to_protect_db_pool(
monkeypatch,
):
runtime_control_module._clear_runtime_receipt_readback_cache()
calls = 0
async def _fake_uncached_loader(
*,
project_id: str,
lookback_hours: int,
limit: int,
) -> dict:
nonlocal calls
calls += 1
return build_runtime_receipt_readback_from_rows(
project_id=project_id,
lookback_hours=lookback_hours,
db_read_status="ok",
service_log_count_rows=[
{"status": "sanitized_recent_logs", "total": calls, "recent": calls},
],
)
monkeypatch.setattr(
runtime_control_module,
"_load_ai_agent_autonomous_runtime_receipt_readback_uncached",
_fake_uncached_loader,
)
try:
first = await runtime_control_module.load_ai_agent_autonomous_runtime_receipt_readback()
second = await runtime_control_module.load_ai_agent_autonomous_runtime_receipt_readback()
finally:
runtime_control_module._clear_runtime_receipt_readback_cache()
assert calls == 1
assert first["db_read_status"] == "ok"
assert second["db_read_status"] == "ok"
assert (
second["log_integration_taxonomy"]["rollups"]["classified_event_total"]
== first["log_integration_taxonomy"]["rollups"]["classified_event_total"]
)
@pytest.mark.asyncio
async def test_live_runtime_receipt_readback_does_not_cache_pool_unavailable(
monkeypatch,
):
runtime_control_module._clear_runtime_receipt_readback_cache()
calls = 0
async def _fake_uncached_loader(
*,
project_id: str,
lookback_hours: int,
limit: int,
) -> dict:
nonlocal calls
calls += 1
if calls == 1:
return build_runtime_receipt_readback_from_rows(
project_id=project_id,
lookback_hours=lookback_hours,
db_read_status="unavailable",
error_type="TimeoutError",
)
return build_runtime_receipt_readback_from_rows(
project_id=project_id,
lookback_hours=lookback_hours,
db_read_status="ok",
service_log_count_rows=[
{"status": "sanitized_recent_logs", "total": 3, "recent": 1},
],
)
monkeypatch.setattr(
runtime_control_module,
"_load_ai_agent_autonomous_runtime_receipt_readback_uncached",
_fake_uncached_loader,
)
try:
first = await runtime_control_module.load_ai_agent_autonomous_runtime_receipt_readback()
second = await runtime_control_module.load_ai_agent_autonomous_runtime_receipt_readback()
finally:
runtime_control_module._clear_runtime_receipt_readback_cache()
assert calls == 2
assert first["db_read_status"] == "unavailable"
assert second["db_read_status"] == "ok"
def test_runtime_control_rollups_project_consumer_dispatch_ledger_if_trace_missing():
payload = build_ai_agent_autonomous_runtime_control()
readback = build_runtime_receipt_readback_from_rows(