/simplify-code quality pass on the final #133283 stack, no behaviour change: - One null-safe is_recurring in cron/constants.py replaces scheduler_tick's new copy and unreachable_retry's (whose .get("schedule", {}) raised on a null schedule). - cron status / cron list share _probe_then_list_jobs (probe, print, guarded read) instead of two near-identical blocks. - StoreDegraded.notice_fields and probe_report build their fields through one _report_fields. - The notice listener's pre-checks no longer repeat deliver()'s store re-check; deliver() is the single staleness gate (still red when removed).
23 lines
1.2 KiB
Python
23 lines
1.2 KiB
Python
"""Fire-claim timing bounds shared by the job store and its siblings.
|
|
|
|
Import-free on purpose: a sibling loaded fresh from a newer on-disk tree must resolve
|
|
these without going through the ``cron.jobs`` object a long-lived process cached at boot.
|
|
"""
|
|
|
|
# A fire_claim younger than this is a live run (heartbeat cadence is 60 s). One value
|
|
# for claiming, one-shot re-arm, and stale-error recovery so they cannot disagree.
|
|
FIRE_CLAIM_TTL_SECONDS = 300
|
|
# A hosted/webhook fire for the armed slot can arrive a few seconds before the stored
|
|
# ``next_run_at`` (the fire scheduler's clock runs ahead of ours). Claims that early still own
|
|
# the slot; only claims further ahead are off-tick manual/dashboard fires.
|
|
FIRE_CLAIM_SKEW_SECONDS = 60
|
|
# Multiplier over HERMES_CRON_TIMEOUT for claim TTLs: the timeout is an *inactivity* limit, not a
|
|
# wall-clock cap, so healthy runs may legitimately exceed it and a TTL of exactly the timeout
|
|
# would expire live claims.
|
|
CLAIM_TTL_INACTIVITY_HEADROOM = 3
|
|
|
|
|
|
def is_recurring(job: dict) -> bool:
|
|
"""A cron/interval job (vs a one-shot); a null ``schedule`` counts as not recurring."""
|
|
return (job.get("schedule") or {}).get("kind") in {"cron", "interval"}
|