From fecaf3afae83df06c6362c2d7c6991d64df20b86 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Sat, 26 Sep 2026 19:35:57 +0530 Subject: [PATCH] refactor(cron): name the retry ladder applicability gate once plan_retry's exhausted-ladder warning re-listed _ladder_instant's gates (recurring, not paused, retry enabled) by hand, so the two could drift and the warning fire for a job the ladder never applied to. Both now call _ladder_applies(job). _ladder_instant checks the attempt count first, so the exhausted path loads config exactly once (in the warning gate). Behaviour unchanged: old-vs-new equivalence over 1,728 job states (will_retry, plan_retry result, mutated job, log levels) shows 0 diffs. --- cron/unreachable_retry.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cron/unreachable_retry.py b/cron/unreachable_retry.py index 05dde275eb..7c0298d4d1 100644 --- a/cron/unreachable_retry.py +++ b/cron/unreachable_retry.py @@ -68,16 +68,19 @@ def _is_recurring(job: Dict[str, Any]) -> bool: return job.get("schedule", {}).get("kind") in {"cron", "interval"} +def _ladder_applies(job: Dict[str, Any]) -> bool: + """The ladder's applicability gate: recurring, not paused, and enabled in config.""" + return _is_recurring(job) and job.get("state") != "paused" and retry_enabled() + + def _ladder_instant(job: Dict[str, Any], natural_next: Optional[datetime], now: datetime) -> Optional[datetime]: """The ladder instant ``plan_retry`` parks for this flagged failure, or None when it parks nothing: not recurring, paused, disabled, ladder exhausted, or the schedule's own *natural_next* fires at or before the rung. The single source of that decision for ``plan_retry`` and ``will_retry``.""" - if not _is_recurring(job) or job.get("state") == "paused": - return None attempt = int((job.get(STATE_KEY) or {}).get("attempt") or 0) - if attempt >= len(RETRY_DELAYS_SECONDS) or not retry_enabled(): + if attempt >= len(RETRY_DELAYS_SECONDS) or not _ladder_applies(job): return None # late: jobs imports this module's helpers from cron.jobs import _instant_at_or_before, _seconds_after @@ -132,8 +135,7 @@ def plan_retry(job: Dict[str, Any]) -> bool: retry_dt = _ladder_instant(job, _parse_aware(job.get("next_run_at")), _hermes_now()) attempt = int((job.get(STATE_KEY) or {}).get("attempt") or 0) if retry_dt is None: - if (attempt >= len(RETRY_DELAYS_SECONDS) and _is_recurring(job) - and job.get("state") != "paused" and retry_enabled()): + if attempt >= len(RETRY_DELAYS_SECONDS) and _ladder_applies(job): # Ladder exhausted: fall back to the natural schedule and reset so the NEXT # occurrence gets a fresh ladder if the network is still down. logger.warning(