fix(cron): review follow-ups for system job retirement

- advance the disabled-dream cursor before touching the cron store so
  the #4242 fix still applies when jobs.json is corrupt
- pin the gateway wiring: the disabled-path test now asserts both
  dream and heartbeat are retired, not just unregistered
- cover remove_system_job on a fresh install with no store file
This commit is contained in:
aiguozhi123456
2026-08-22 02:38:47 +08:00
committed by chengyongru
parent e5718d4de6
commit 20488a585d
3 changed files with 16 additions and 2 deletions
+3 -1
View File
@@ -785,8 +785,10 @@ def _run_gateway(
console.print(f"[green]✓[/green] Dream: {dream_cfg.describe_schedule()}")
else:
console.print("[yellow]○[/yellow] Dream: disabled")
cron.remove_system_job("dream")
# Advance the cursor first: it must happen unconditionally (issue
# #4242), even if the cron store turns out to be corrupt below.
_advance_dream_cursor_if_behind(agent.context.memory)
cron.remove_system_job("dream")
# Register Heartbeat system job (idempotent on restart)
if hb_cfg.enabled:
+4 -1
View File
@@ -3221,7 +3221,8 @@ def test_gateway_local_trigger_queue_submits_agent_turns(
def register_system_job(self, _job) -> None:
return None
def remove_system_job(self, _job_id: str) -> bool:
def remove_system_job(self, job_id: str) -> bool:
seen.setdefault("removed_system_jobs", []).append(job_id)
return False
class _FakeAgentLoop(_GatewayAgentContractStub):
@@ -3300,6 +3301,8 @@ def test_gateway_local_trigger_queue_submits_agent_turns(
turn_delivery_factory = agent_kwargs["turn_delivery_factory"]
assert isinstance(turn_delivery_factory, TurnDeliveryFactory)
assert turn_delivery_factory.bus is bus
# Disabled system jobs must be retired on startup, not just unregistered.
assert seen["removed_system_jobs"] == ["dream", "heartbeat"]
assert isinstance(turn_delivery_factory.route_policy, WebuiTurnRoutePolicy)
assert turn_delivery_factory.route_policy.sessions is agent.sessions
+9
View File
@@ -818,6 +818,15 @@ def test_remove_system_job_retires_persisted_system_job(tmp_path) -> None:
assert other.remove_job("dream") == "protected"
def test_remove_system_job_without_store_file(tmp_path) -> None:
"""Fresh install with the system job disabled: no jobs.json exists yet."""
store_path = tmp_path / "cron" / "jobs.json"
service = CronService(store_path)
assert service.remove_system_job("heartbeat") is False
assert not store_path.exists()
@pytest.mark.asyncio
async def test_start_server_not_jobs(tmp_path):
store_path = tmp_path / "cron" / "jobs.json"